Putting It All Back Together

Throughout all the data analysis we’ve done, the datasets have become more fragmented - lexical recall, gist, and eye tracking datasets. I want to put them all together in one whole dataset again so we can perform some analyses more efficiently (particularly correlations). The only thing I need to remember is we’ll have a new column called eye_exclude and if it is set to TRUE it means we can’t include that row in any analysis relating to eye gaze (usually because that trial was less than 25% looking).

# Libraries
library(tidyverse)
Warning message:
In as.POSIXlt.POSIXct(Sys.time()) :
  unknown timezone 'zone/tz/2017c.1.0/zoneinfo/America/Los_Angeles'
library(lme4)
library(lmerTest)
library(scales)
library(viridis)
library(agricolae) 
library(GGally)
# Load lex and eye data
cleanlexdata <- read_csv("cleandata.csv") %>%
  select(-(forehead:total))
cleaneyedata <- read_csv("cleanpercentdata.csv") %>%
  spread(aoi,percent) %>%
  add_column(eye_exclude = FALSE)
# What rows were removed from the eye data back in 03eyegaze? Let's add back in
# With a new column - eye_exclude
removed <- anti_join(cleanlexdata, cleaneyedata) %>%
  add_column(eye_exclude = TRUE)
eyelexdata <- bind_rows(cleaneyedata, removed)
# Load gist data
gist <- read_csv('gist_indiv.csv', col_types = cols(
  participant = col_character(),
  gist.fw1 = col_integer(),
  gist.rv2 = col_integer(),
  gist.fw3 = col_integer(),
  gist.rv4 = col_integer()
)) %>%
  gather(video, gist, gist.fw1:gist.rv4) %>%
  mutate(video = str_sub(video,6,8))
# Presto, our full reunified dataset - 'fulldata'
# But I want to remove columns I don't want anymore and will recalculate later
fulldata <- left_join(eyelexdata, gist) %>%
  select(-moutheye, -facechest, -face, -chest)

Group Changes and Participant Tables

We have some changes to make to the groups. First, fix Josh as learning ASL when he was 6. Next, drop the DeafNative Group and reclassify all who learned ASL < 3.9 as DeafEarly and ASL => 4.0 as DeafLate.

# Change Josh's AoASL to 6
fulldata <- fulldata %>%
  mutate(aoasl = as.double(aoasl)) %>%
  mutate(aoasl = case_when(
    participant == "Josh" ~ 6,
    TRUE ~ aoasl
  ))
# Reclassify Groups
fulldata <- fulldata %>%
  mutate(maingroup = case_when(
    hearing == "Deaf" & aoasl < 4 ~ "DeafEarly",
    hearing == "Deaf" & aoasl >= 4 ~ "DeafLate",
    maingroup == "HearingLateASL" ~ "HearingLate",
    maingroup == "HearingNoviceASL" ~ "HearingNovice"
  ))
# Create Participant Demographics Table
participant_info <- fulldata %>%
  select(-(acc:gist)) %>%
  select(-(video:direction)) %>%
  distinct() %>% 
  group_by(maingroup) %>%
  summarise(n = n(),
            age_mean = mean(age),
            age_sd = sd(age),
            aoasl_mean = mean(aoasl),
            aoasl_sd = sd(aoasl),
            signyrs_mean = mean(signyrs),
            signyrs_sd = sd(signyrs),
            selfrate_mean = mean(selfrate),
            selfrate_sd = sd(selfrate)) %>%
  ungroup() %>%
  mutate_if(is.double, funs(round(., 2))) %>%
  mutate(age = paste(age_mean, "±", age_sd, sep = " "),
         aoasl = paste(aoasl_mean, "±", aoasl_sd, sep = " "),
         signyrs = paste(signyrs_mean, "±", signyrs_sd, sep = " "),
         selfrate = paste(selfrate_mean, "±", selfrate_sd, sep = " ")) %>%
  select(-(age_mean:selfrate_sd))
participant_info

Participant ANOVAs

Below are the ANOVA outputs for participant demographics, and LSDs for each.

Participants’ age

            Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup    3   1810   603.3   14.29 8.75e-07 ***
Residuals   48   2026    42.2                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Participants’ AoASL

            Df Sum Sq Mean Sq F value Pr(>F)    
maingroup    3 2553.9   851.3   89.98 <2e-16 ***
Residuals   48  454.1     9.5                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Participants’ Sign Yrs

            Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup    3   7032  2344.1   59.37 3.52e-16 ***
Residuals   48   1895    39.5                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Participants’ Self-Rating

            Df Sum Sq Mean Sq F value Pr(>F)    
maingroup    3  30.71  10.237   72.37 <2e-16 ***
Residuals   48   6.79   0.141                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Gist & Lexical Recall Data

Tables & Charts

Let’s generate a table for lexical recall and gist for forward vs. reversed stories.

lexgist_info <- fulldata %>%
  group_by(maingroup, direction) %>%
  summarise(lex_mean = mean(acc, na.rm = TRUE),
            lex_sd = sd(acc, na.rm = TRUE),
            gist_mean = mean(gist),
            gist_sd = sd(gist)) %>%
  ungroup() %>%
  mutate_if(is.double, funs(round(., 2))) %>% 
  mutate(lex = paste(lex_mean, "±", lex_sd, sep = " "),
         gist = paste(gist_mean, "±", gist_sd, sep = " ")) %>%
  select(-(lex_mean:gist_sd)) %>%
  gather(metric, value, lex:gist) %>%
  unite("metric", c(metric, direction), sep = "_") %>%
  spread(metric, value) %>%
  print()

And then bar charts too after that with error bars.

# Gist bar chart
gist_bar <- fulldata %>% select(participant, maingroup, direction, gist) %>%
  group_by(maingroup, participant, direction) %>%
  summarise(gist = mean(gist)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(gist),
            sd = sd(gist),
            count = n(),
            se = sd/sqrt(count))
ggplot(gist_bar, aes(x = maingroup, y = mean, fill = direction)) +
  geom_bar(stat = "identity", position = position_dodge()) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "Story Comprehension (Gist)", subtitle = "Error bars represent SE", x = "", y = "mean gist") +
  scale_y_continuous(labels = percent, limits = c(0,1))

# Lex bar chart
lex_bar <- fulldata %>% select(participant, maingroup, direction, acc) %>%
  group_by(maingroup, participant, direction) %>%
  summarise(acc = mean(acc, na.rm = TRUE)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(acc, na.rm = TRUE),
            sd = sd(acc, na.rm = TRUE),
            count = n(),
            se = sd/sqrt(count))
ggplot(lex_bar, aes(x = maingroup, y = mean, fill = direction)) +
  geom_bar(stat = "identity", position = position_dodge()) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "Lexical Recall", subtitle = "Error bars represent SE", x = "", y = "mean accuracy") +
  scale_y_continuous(labels = percent, limits = c(0,1)) +
  geom_hline(yintercept = .5, linetype = "dotted") +
  coord_cartesian(ylim = c(.5,1))

ANOVA Plan

Next, we’re going to do ANOVAs and ANCOVAs. We’ll always do it in this order. The first three ANOVAs will be followed by LSD of the four maingroups with uncorrected p-values.

  1. ANOVA with factors MainGroup & Direction
  2. ANOVA with factor MainGroup, for Forward only
  3. ANOVA with factor MainGroup, for Reverse only
  4. ANCOVA with factor Direction, and covariate AoASL and Age
  5. Regression with variables AoASL and Age, for Forward only
  6. Regression with variables AoASL and Age, for Reverse only.

I did not include Age as a covariate in the first 3 ANOVAs because they did not add to or change the model in any significant way.

Gist ANOVAs

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup            3  3.002   1.001  13.284 2.53e-07 ***
direction            1  5.310   5.310  70.491 4.10e-13 ***
maingroup:direction  3  0.896   0.299   3.965   0.0103 *  
Residuals           96  7.232   0.075                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only. Also a Kruskal-Wallis test. And Chi-Sq too.
            Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup    3  2.477  0.8256   16.11 2.23e-07 ***
Residuals   48  2.461  0.0513                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

    Kruskal-Wallis rank sum test

data:  gist by maingroup
Kruskal-Wallis chi-squared = 25.46, df = 3, p-value = 1.237e-05
Chi-squared approximation may be incorrect

    Pearson's Chi-squared test

data:  gist_chisq_fw
X-squared = 26.984, df = 6, p-value = 0.0001458
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value  Pr(>F)   
maingroup    3  1.421  0.4737   4.766 0.00548 **
Residuals   48  4.771  0.0994                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

    Kruskal-Wallis rank sum test

data:  gist by maingroup
Kruskal-Wallis chi-squared = 11.365, df = 3, p-value = 0.009907
Chi-squared approximation may be incorrect

    Pearson's Chi-squared test

data:  gist_chisq_rv
X-squared = 15.056, df = 6, p-value = 0.01982
  1. ANCOVA with factor Direction, and variables AoASL and Age.
                    Df Sum Sq Mean Sq F value   Pr(>F)    
direction            1  5.310   5.310  61.435 6.24e-12 ***
aoasl                1  1.435   1.435  16.602 9.50e-05 ***
age                  1  0.524   0.524   6.058   0.0156 *  
direction:aoasl      1  0.033   0.033   0.386   0.5360    
direction:age        1  0.216   0.216   2.493   0.1176    
aoasl:age            1  0.579   0.579   6.703   0.0111 *  
direction:aoasl:age  1  0.045   0.045   0.524   0.4707    
Residuals           96  8.298   0.086                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = gist ~ aoasl * age, data = filter(participant_data, 
    direction == "forward"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.64682 -0.04576  0.00158  0.12355  0.42535 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  1.0541328  0.2576559   4.091 0.000163 ***
aoasl       -0.0551054  0.0184504  -2.987 0.004431 ** 
age         -0.0016630  0.0074651  -0.223 0.824659    
aoasl:age    0.0015158  0.0005719   2.650 0.010863 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2599 on 48 degrees of freedom
Multiple R-squared:  0.3434,    Adjusted R-squared:  0.3023 
F-statistic: 8.366 on 3 and 48 DF,  p-value: 0.0001409
  1. Regression with variables AoASL and Age, for Reverse only.

Call:
lm(formula = gist ~ aoasl * age, data = filter(participant_data, 
    direction == "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.63610 -0.22752  0.02114  0.24941  0.61943 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept)  0.8059325  0.3217367   2.505   0.0157 *
aoasl       -0.0431909  0.0230392  -1.875   0.0669 .
age         -0.0058563  0.0093218  -0.628   0.5328  
aoasl:age    0.0008532  0.0007142   1.195   0.2381  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3245 on 48 degrees of freedom
Multiple R-squared:  0.1836,    Adjusted R-squared:  0.1326 
F-statistic: 3.598 on 3 and 48 DF,  p-value: 0.02002

Lexical Recall ANOVAs

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value   Pr(>F)    
maingroup            3 0.1175  0.0392   5.348  0.00189 ** 
direction            1 0.5211  0.5211  71.149 3.38e-13 ***
maingroup:direction  3 0.0294  0.0098   1.336  0.26731    
Residuals           96 0.7031  0.0073                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only.
            Df  Sum Sq  Mean Sq F value Pr(>F)  
maingroup    3 0.04988 0.016626   2.984 0.0404 *
Residuals   48 0.26749 0.005573                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)  
maingroup    3 0.0970 0.03233   3.562 0.0209 *
Residuals   48 0.4356 0.00908                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value   Pr(>F)    
direction            1 0.5211  0.5211  69.354 5.72e-13 ***
aoasl                1 0.0431  0.0431   5.731   0.0186 *  
age                  1 0.0347  0.0347   4.621   0.0341 *  
direction:aoasl      1 0.0204  0.0204   2.716   0.1026    
direction:age        1 0.0094  0.0094   1.253   0.2658    
aoasl:age            1 0.0195  0.0195   2.602   0.1100    
direction:aoasl:age  1 0.0015  0.0015   0.202   0.6540    
Residuals           96 0.7213  0.0075                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = acc ~ aoasl * age, data = filter(participant_data, 
    direction == "forward"))

Residuals:
      Min        1Q    Median        3Q       Max 
-0.223429 -0.032150  0.004461  0.039614  0.205706 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.7878168  0.0743596  10.595 3.69e-14 ***
aoasl       -0.0045003  0.0053248  -0.845    0.402    
age          0.0017563  0.0021544   0.815    0.419    
aoasl:age    0.0001569  0.0001651   0.951    0.347    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.07501 on 48 degrees of freedom
Multiple R-squared:  0.1491,    Adjusted R-squared:  0.09593 
F-statistic: 2.804 on 3 and 48 DF,  p-value: 0.04966
  1. Regression with variables AoASL and Age, for Reverse only.

Call:
lm(formula = acc ~ aoasl * age, data = filter(participant_data, 
    direction == "reversed"))

Residuals:
      Min        1Q    Median        3Q       Max 
-0.243150 -0.053718  0.000822  0.061438  0.212639 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.8084021  0.0961239   8.410 5.33e-11 ***
aoasl       -0.0127774  0.0068833  -1.856   0.0696 .  
age         -0.0018529  0.0027850  -0.665   0.5090    
aoasl:age    0.0002782  0.0002134   1.304   0.1985    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.09696 on 48 degrees of freedom
Multiple R-squared:  0.1527,    Adjusted R-squared:  0.09977 
F-statistic: 2.884 on 3 and 48 DF,  p-value: 0.04527

AoA Correlations

Next, we want to look at correlations between AoA and Gist, and betwen AoA and Lexical Recall. Rain asked for forward and reversed separately (1) deaf only, (2) hearing only, and (3) both. Let’s make it work.

# Let's make participant-level data, and have forward/reversed in separate columns
lexgist_data <- fulldata %>%
  group_by(maingroup, participant, direction) %>%
  mutate(gist = mean(gist, na.rm = TRUE),
         lex = mean(acc, na.rm = TRUE)) %>%
  ungroup() %>%
  select(maingroup, participant, hearing, direction, aoasl, signyrs, age, gist, lex) %>%
  distinct() %>%
  gather(metric, value, gist:lex) %>%
  unite(metricvalue, c(metric, direction), sep = "_") %>%
  spread(metricvalue, value) %>%
  select(-participant, -maingroup)
lexgist_deaf <- lexgist_data %>% filter(hearing == "Deaf") %>% select(-hearing)
lexgist_hearing <- lexgist_data %>% filter(hearing == "Hearing") %>% select(-hearing)
lexgist_all <- lexgist_data %>% select(-hearing)
# Load awesome function to make correlation tables with stars for significance
# From: https://myowelt.blogspot.co.uk/2008/04/beautiful-correlation-tables-in-r.html
corstarsl <- function(x){ 
require(Hmisc) 
x <- as.matrix(x) 
R <- Hmisc::rcorr(x)$r 
p <- Hmisc::rcorr(x)$P 
## define notions for significance levels; spacing is important.
mystars <- ifelse(p < .001, "***", ifelse(p < .01, "** ", ifelse(p < .05, "* ", " ")))
## trunctuate the matrix that holds the correlations to two decimal
R <- format(round(cbind(rep(-1.11, ncol(x)), R), 2))[,-1] 
## build a new matrix that includes the correlations with their apropriate stars 
Rnew <- matrix(paste(R, mystars, sep=""), ncol=ncol(x)) 
diag(Rnew) <- paste(diag(R), " ", sep="") 
rownames(Rnew) <- colnames(x) 
colnames(Rnew) <- paste(colnames(x), "", sep="") 
## remove upper triangle
Rnew <- as.matrix(Rnew)
Rnew[upper.tri(Rnew, diag = TRUE)] <- ""
Rnew <- as.data.frame(Rnew) 
## remove last column and return the matrix (which is now a data frame)
Rnew <- cbind(Rnew[1:length(Rnew)-1])
return(Rnew) 
}
# Correlations for Deaf
print("DEAF Correlations - Pearson's r")
[1] "DEAF Correlations - Pearson's r"
#corstarsl(lexgist_deaf)
Hmisc::rcorr(as.matrix(lexgist_deaf))$r
                    aoasl     signyrs        age gist_forward gist_reversed lex_forward lex_reversed
aoasl          1.00000000 -0.50188273  0.2569266   0.08266371   -0.25585943  0.14743346  -0.25601873
signyrs       -0.50188273  1.00000000  0.7005996   0.18321127   -0.01264108  0.27968505   0.06666998
age            0.25692660  0.70059955  1.0000000   0.27454460   -0.17264941  0.42997837  -0.12765634
gist_forward   0.08266371  0.18321127  0.2745446   1.00000000    0.01762269 -0.08155560  -0.09770666
gist_reversed -0.25585943 -0.01264108 -0.1726494   0.01762269    1.00000000  0.02667231   0.36021802
lex_forward    0.14743346  0.27968505  0.4299784  -0.08155560    0.02667231  1.00000000   0.35984892
lex_reversed  -0.25601873  0.06666998 -0.1276563  -0.09770666    0.36021802  0.35984892   1.00000000
print("DEAF Correlations - P-values")
[1] "DEAF Correlations - P-values"
Hmisc::rcorr(as.matrix(lexgist_deaf))$P
                    aoasl      signyrs          age gist_forward gist_reversed lex_forward lex_reversed
aoasl                  NA 5.536857e-03 1.784812e-01    0.6698839    0.18035489  0.44533530   0.18007434
signyrs       0.005536857           NA 2.316796e-05    0.3414473    0.94810844  0.14172236   0.73113301
age           0.178481213 2.316796e-05           NA    0.1495001    0.37046625  0.01990877   0.50930544
gist_forward  0.669883883 3.414473e-01 1.495001e-01           NA    0.92770438  0.67406661   0.61409897
gist_reversed 0.180354888 9.481084e-01 3.704662e-01    0.9277044            NA  0.89076140   0.05492031
lex_forward   0.445335297 1.417224e-01 1.990877e-02    0.6740666    0.89076140          NA   0.05518766
lex_reversed  0.180074336 7.311330e-01 5.093054e-01    0.6140990    0.05492031  0.05518766           NA
cat(paste("","\n",""))
# Correlations for Hearing
print("HEARING Correlations - Pearson's r")
[1] "HEARING Correlations - Pearson's r"
#corstarsl(lexgist_hearing)
Hmisc::rcorr(as.matrix(lexgist_hearing))$r
                    aoasl     signyrs       age gist_forward gist_reversed lex_forward lex_reversed
aoasl          1.00000000 -0.07887013 0.3468184  -0.15525565    0.07815751  0.02500269   0.01411303
signyrs       -0.07887013  1.00000000 0.9021947   0.57814670    0.28845748  0.36725658   0.20828810
age            0.34681845  0.90219468 1.0000000   0.44651473    0.30963454  0.30931753   0.20139593
gist_forward  -0.15525565  0.57814670 0.4465147   1.00000000    0.29502174  0.57154566   0.07645807
gist_reversed  0.07815751  0.28845748 0.3096345   0.29502174    1.00000000  0.35682374   0.57951176
lex_forward    0.02500269  0.36725658 0.3093175   0.57154566    0.35682374  1.00000000   0.36558339
lex_reversed   0.01411303  0.20828810 0.2013959   0.07645807    0.57951176  0.36558339   1.00000000
print("HEARING Correlations - P-values")
[1] "HEARING Correlations - P-values"
Hmisc::rcorr(as.matrix(lexgist_hearing))$P
                  aoasl      signyrs          age gist_forward gist_reversed lex_forward lex_reversed
aoasl                NA 7.205586e-01 1.049514e-01  0.479339909   0.722986497 0.909841021  0.949040176
signyrs       0.7205586           NA 4.046899e-09  0.003857505   0.181932462 0.084723426  0.340222805
age           0.1049514 4.046899e-09           NA  0.032691671   0.150502508 0.150942632  0.356794880
gist_forward  0.4793399 3.857505e-03 3.269167e-02           NA   0.171744860 0.004385475  0.728786878
gist_reversed 0.7229865 1.819325e-01 1.505025e-01  0.171744860            NA 0.094647552  0.003755275
lex_forward   0.9098410 8.472343e-02 1.509426e-01  0.004385475   0.094647552          NA  0.086260140
lex_reversed  0.9490402 3.402228e-01 3.567949e-01  0.728786878   0.003755275 0.086260140           NA
cat(paste("","\n",""))
# Correlations for All
print("ALL Correlations - Pearson's r")
[1] "ALL Correlations - Pearson's r"
#corstarsl(lexgist_all)
Hmisc::rcorr(as.matrix(lexgist_all))$r
                    aoasl    signyrs        age gist_forward gist_reversed lex_forward lex_reversed
aoasl          1.00000000 -0.7852245 -0.3136458   -0.3230903    -0.3922803 -0.08115845   -0.3394521
signyrs       -0.78522450  1.0000000  0.8314757    0.4956183     0.3356193  0.29698992    0.3182316
age           -0.31364575  0.8314757  1.0000000    0.4602616     0.1930257  0.36318284    0.1886432
gist_forward  -0.32309031  0.4956183  0.4602616    1.0000000     0.2712761  0.49279109    0.1521110
gist_reversed -0.39228034  0.3356193  0.1930257    0.2712761     1.0000000  0.21701819    0.4921550
lex_forward   -0.08115845  0.2969899  0.3631828    0.4927911     0.2170182  1.00000000    0.3800772
lex_reversed  -0.33945209  0.3182316  0.1886432    0.1521110     0.4921550  0.38007715    1.0000000
print("ALL Correlations - P-values")
[1] "ALL Correlations - P-values"
Hmisc::rcorr(as.matrix(lexgist_all))$P
                     aoasl      signyrs          age gist_forward gist_reversed  lex_forward lex_reversed
aoasl                   NA 5.523138e-12 2.356068e-02 0.0194786567  0.0040239673 0.5673489939 0.0138201778
signyrs       5.523138e-12           NA 2.309264e-14 0.0001870211  0.0150006737 0.0325116001 0.0214967644
age           2.356068e-02 2.309264e-14           NA 0.0005965582  0.1703671221 0.0081373882 0.1804672184
gist_forward  1.947866e-02 1.870211e-04 5.965582e-04           NA  0.0517394597 0.0002061625 0.2817023354
gist_reversed 4.023967e-03 1.500067e-02 1.703671e-01 0.0517394597            NA 0.1222542968 0.0002107074
lex_forward   5.673490e-01 3.251160e-02 8.137388e-03 0.0002061625  0.1222542968           NA 0.0054478274
lex_reversed  1.382018e-02 2.149676e-02 1.804672e-01 0.2817023354  0.0002107074 0.0054478274           NA

I’m also including nicely formatted tables with *** indicators of significance for quick referencing. Order: Deaf, Hearing, All.

corstarsl(lexgist_deaf)
Loading required package: Hmisc
Loading required package: lattice
Loading required package: survival
Loading required package: Formula

Attaching package: ‘Hmisc’

The following objects are masked from ‘package:dplyr’:

    combine, src, summarize

The following objects are masked from ‘package:base’:

    format.pval, round.POSIXt, trunc.POSIXt, units
corstarsl(lexgist_hearing)
corstarsl(lexgist_all)

Scatterplot of Correlations

Let’s visualize what’s happening with the correlations here.

ggpairs(lexgist_data, columns = c(2:8), aes(color = hearing))

 plot: [1,1] [==--------------------------------------------------------------------------]  2% est: 0s 
 plot: [1,2] [===-------------------------------------------------------------------------]  4% est: 6s 
 plot: [1,3] [=====-----------------------------------------------------------------------]  6% est: 6s 
 plot: [1,4] [======----------------------------------------------------------------------]  8% est: 7s 
 plot: [1,5] [========--------------------------------------------------------------------] 10% est: 6s 
 plot: [1,6] [=========-------------------------------------------------------------------] 12% est: 6s 
 plot: [1,7] [===========-----------------------------------------------------------------] 14% est: 5s 
 plot: [2,1] [============----------------------------------------------------------------] 16% est: 5s 
 plot: [2,2] [==============--------------------------------------------------------------] 18% est: 5s 
 plot: [2,3] [================------------------------------------------------------------] 20% est: 5s 
 plot: [2,4] [=================-----------------------------------------------------------] 22% est: 5s 
 plot: [2,5] [===================---------------------------------------------------------] 24% est: 5s 
 plot: [2,6] [====================--------------------------------------------------------] 27% est: 4s 
 plot: [2,7] [======================------------------------------------------------------] 29% est: 4s 
 plot: [3,1] [=======================-----------------------------------------------------] 31% est: 5s 
 plot: [3,2] [=========================---------------------------------------------------] 33% est: 4s 
 plot: [3,3] [==========================--------------------------------------------------] 35% est: 4s 
 plot: [3,4] [============================------------------------------------------------] 37% est: 4s 
 plot: [3,5] [=============================-----------------------------------------------] 39% est: 4s 
 plot: [3,6] [===============================---------------------------------------------] 41% est: 4s 
 plot: [3,7] [=================================-------------------------------------------] 43% est: 4s 
 plot: [4,1] [==================================------------------------------------------] 45% est: 3s 
 plot: [4,2] [====================================----------------------------------------] 47% est: 3s 
 plot: [4,3] [=====================================---------------------------------------] 49% est: 3s 
 plot: [4,4] [=======================================-------------------------------------] 51% est: 3s 
 plot: [4,5] [========================================------------------------------------] 53% est: 3s 
 plot: [4,6] [==========================================----------------------------------] 55% est: 3s 
 plot: [4,7] [===========================================---------------------------------] 57% est: 3s 
 plot: [5,1] [=============================================-------------------------------] 59% est: 2s 
 plot: [5,2] [===============================================-----------------------------] 61% est: 2s 
 plot: [5,3] [================================================----------------------------] 63% est: 2s 
 plot: [5,4] [==================================================--------------------------] 65% est: 2s 
 plot: [5,5] [===================================================-------------------------] 67% est: 2s 
 plot: [5,6] [=====================================================-----------------------] 69% est: 2s 
 plot: [5,7] [======================================================----------------------] 71% est: 2s 
 plot: [6,1] [========================================================--------------------] 73% est: 2s 
 plot: [6,2] [=========================================================-------------------] 76% est: 1s 
 plot: [6,3] [===========================================================-----------------] 78% est: 1s 
 plot: [6,4] [============================================================----------------] 80% est: 1s 
 plot: [6,5] [==============================================================--------------] 82% est: 1s 
 plot: [6,6] [================================================================------------] 84% est: 1s 
 plot: [6,7] [=================================================================-----------] 86% est: 1s 
 plot: [7,1] [===================================================================---------] 88% est: 1s 
 plot: [7,2] [====================================================================--------] 90% est: 1s 
 plot: [7,3] [======================================================================------] 92% est: 1s 
 plot: [7,4] [=======================================================================-----] 94% est: 0s 
 plot: [7,5] [=========================================================================---] 96% est: 0s 
 plot: [7,6] [==========================================================================--] 98% est: 0s 
 plot: [7,7] [============================================================================]100% est: 0s 
                                                                                                        

Eye Gaze Data

Now eye gaze data. Boxplots first. Also here, we’re renaming “chin” to “neck” because that’s what it actually is! But we also have to fix all NA’s in the percentages to zeros, becuase that’s what they actually are.

# rename chin to neck
fulldata <- fulldata %>%
  rename(neck = chin) %>%
  gather(aoi, percent, belly:upperchest)
# Fix all NA's in Percent column to 0
fixpercent <- fulldata$percent
fulldata$percent <- coalesce(fixpercent, 0)
fulldata <- fulldata %>%
  spread(aoi, percent)
fulldata %>%
  filter(eye_exclude == FALSE) %>%
  select(direction, belly:upperchest) %>%
  gather(aoi, percent, belly:upperchest) %>%
  ggplot(aes(x = aoi, y = percent, fill = direction)) + geom_boxplot()

But let’s try error charts too! Instead of boxplots.

fulldata_error <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  gather(aoi, percent, belly:upperchest) %>%
  group_by(id, direction, aoi) %>%
  summarise(percent = mean(percent, na.rm = TRUE)) %>%
  ungroup() %>%
  distinct() %>%
  group_by(direction, aoi) %>%
  summarise(mean = mean(percent, na.rm = TRUE),
            sd = sd(percent, na.rm = TRUE),
            count = n(),
            se = sd/sqrt(count))
fulldata_error$aoi <- fct_relevel(fulldata_error$aoi, c("forehead","eyes","mouth","neck","upperchest",
                                                        "midchest","lowerchest","belly","left","right"))
fulldata_error %>%
  ggplot(aes(x = aoi, y = mean, fill = direction)) + 
  geom_bar(stat = "identity", position = position_dodge()) +
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.9), width = 0.5) +
  labs(title = "Eye Gaze Behavior", subtitle = "Error bars represent SE", x = "", y = "percent looking") +
  scale_y_continuous(labels = percent, limits = c(0,.75))

Big Three-Way ANOVA

Now we’re going to try a three-way Group x Direction x AOI ANOVA with the top 3 AOIs (Eyes, Mouth, Neck)

                         Df Sum Sq Mean Sq F value  Pr(>F)    
maingroup                 3  0.031   0.010   0.190 0.90322    
direction                 1  0.012   0.012   0.218 0.64069    
aoi                       2 11.416   5.708 106.365 < 2e-16 ***
maingroup:direction       3  0.002   0.001   0.013 0.99797    
maingroup:aoi             6  0.979   0.163   3.039 0.00676 ** 
direction:aoi             2  0.329   0.164   3.065 0.04820 *  
maingroup:direction:aoi   6  0.079   0.013   0.246 0.96078    
Residuals               285 15.294   0.054                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

All the AOI raw numbers/averages

Let’s get a table of our raw numbers here, by group

Eyes

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value Pr(>F)
maingroup            3  0.315 0.10508   1.936  0.129
direction            1  0.000 0.00000   0.000  0.999
maingroup:direction  3  0.013 0.00425   0.078  0.972
Residuals           95  5.157 0.05429               
  1. ANOVA with factor MainGroup, for Forward only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.1234 0.04114   0.863  0.467
Residuals   48 2.2876 0.04766               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.2046 0.06820   1.117  0.352
Residuals   47 2.8695 0.06105               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value Pr(>F)
direction            1  0.000 0.00000   0.000  0.995
aoasl                1  0.047 0.04669   0.821  0.367
age                  1  0.009 0.00903   0.159  0.691
direction:aoasl      1  0.000 0.00008   0.001  0.971
direction:age        1  0.014 0.01362   0.239  0.626
aoasl:age            1  0.003 0.00258   0.045  0.832
direction:aoasl:age  1  0.007 0.00717   0.126  0.723
Residuals           95  5.406 0.05690               
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = eyes ~ aoasl * age, data = filter(aoi3_data, direction == 
    "forward"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.23543 -0.16625 -0.09484  0.13048  0.60413 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  0.1114653  0.2205845   0.505    0.616
aoasl        0.0093545  0.0157958   0.592    0.556
age          0.0019633  0.0063910   0.307    0.760
aoasl:age   -0.0002108  0.0004897  -0.431    0.669

Residual standard error: 0.2225 on 48 degrees of freedom
Multiple R-squared:  0.01437,   Adjusted R-squared:  -0.04723 
F-statistic: 0.2333 on 3 and 48 DF,  p-value: 0.8727
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = eyes ~ aoasl * age, data = filter(aoi3_data, direction == 
    "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.25646 -0.18517 -0.08579  0.17714  0.62517 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.095e-01  2.517e-01   0.435    0.666
aoasl       1.935e-03  1.803e-02   0.107    0.915
age         2.005e-03  7.300e-03   0.275    0.785
aoasl:age   5.266e-05  5.588e-04   0.094    0.925

Residual standard error: 0.2539 on 47 degrees of freedom
Multiple R-squared:  0.01448,   Adjusted R-squared:  -0.04843 
F-statistic: 0.2302 on 3 and 47 DF,  p-value: 0.8749

Mouth

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value Pr(>F)  
maingroup            3  0.499 0.16623   2.533 0.0616 .
direction            1  0.246 0.24582   3.745 0.0559 .
maingroup:direction  3  0.029 0.00955   0.146 0.9323  
Residuals           95  6.235 0.06563                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.1506 0.05021   0.909  0.444
Residuals   48 2.6511 0.05523               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3  0.368 0.12263   1.608    0.2
Residuals   47  3.584 0.07625               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value  Pr(>F)   
direction            1  0.255  0.2546   3.875 0.05191 . 
aoasl                1  0.037  0.0368   0.561 0.45580   
age                  1  0.459  0.4593   6.991 0.00958 **
direction:aoasl      1  0.003  0.0027   0.041 0.84063   
direction:age        1  0.009  0.0089   0.136 0.71335   
aoasl:age            1  0.001  0.0011   0.017 0.89558   
direction:aoasl:age  1  0.003  0.0030   0.046 0.83099   
Residuals           95  6.242  0.0657                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = mouth ~ aoasl * age, data = filter(aoi3_data, direction == 
    "forward"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.44000 -0.20113  0.06621  0.19821  0.31155 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  0.3649728  0.2314635   1.577    0.121
aoasl        0.0049408  0.0165748   0.298    0.767
age          0.0084860  0.0067063   1.265    0.212
aoasl:age   -0.0001379  0.0005138  -0.268    0.790

Residual standard error: 0.2335 on 48 degrees of freedom
Multiple R-squared:  0.06612,   Adjusted R-squared:  0.007748 
F-statistic: 1.133 on 3 and 48 DF,  p-value: 0.3453
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = mouth ~ aoasl * age, data = filter(aoi3_data, direction == 
    "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.57201 -0.20495  0.01672  0.20824  0.37940 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept)  2.625e-01  2.754e-01   0.953    0.345
aoasl       -8.955e-04  1.972e-02  -0.045    0.964
age          8.966e-03  7.986e-03   1.123    0.267
aoasl:age    3.289e-05  6.112e-04   0.054    0.957

Residual standard error: 0.2777 on 47 degrees of freedom
Multiple R-squared:  0.08266,   Adjusted R-squared:  0.02411 
F-statistic: 1.412 on 3 and 47 DF,  p-value: 0.2511

Neck

  1. ANOVA with factors MainGroup & Direction.
                    Df Sum Sq Mean Sq F value Pr(>F)
maingroup            3  0.195 0.06505   1.584  0.198
direction            1  0.095 0.09484   2.309  0.132
maingroup:direction  3  0.040 0.01326   0.323  0.809
Residuals           95  3.902 0.04107               
  1. ANOVA with factor MainGroup, for Forward only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.0557 0.01857   0.583  0.629
Residuals   48 1.5296 0.03187               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3 0.1758 0.05860   1.161  0.335
Residuals   47 2.3723 0.05048               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value  Pr(>F)   
direction            1  0.098 0.09830   2.499 0.11721   
aoasl                1  0.048 0.04800   1.220 0.27206   
age                  1  0.282 0.28158   7.160 0.00878 **
direction:aoasl      1  0.000 0.00005   0.001 0.97094   
direction:age        1  0.024 0.02403   0.611 0.43638   
aoasl:age            1  0.034 0.03404   0.866 0.35455   
direction:aoasl:age  1  0.010 0.00971   0.247 0.62033   
Residuals           95  3.736 0.03933                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = neck ~ aoasl * age, data = filter(aoi3_data, direction == 
    "forward"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.21315 -0.09850 -0.05872  0.03555  0.59574 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept)  0.4618934  0.1722346   2.682   0.0100 *
aoasl       -0.0181887  0.0123335  -1.475   0.1468  
age         -0.0091690  0.0049902  -1.837   0.0723 .
aoasl:age    0.0004405  0.0003823   1.152   0.2550  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1737 on 48 degrees of freedom
Multiple R-squared:  0.08614,   Adjusted R-squared:  0.02902 
F-statistic: 1.508 on 3 and 48 DF,  p-value: 0.2244
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = neck ~ aoasl * age, data = filter(aoi3_data, direction == 
    "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.26322 -0.14892 -0.05726  0.06747  0.61028 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept)  0.5422914  0.2187298   2.479   0.0168 *
aoasl       -0.0097882  0.0156634  -0.625   0.5351  
age         -0.0096767  0.0063433  -1.525   0.1338  
aoasl:age    0.0001337  0.0004855   0.275   0.7842  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.2206 on 47 degrees of freedom
Multiple R-squared:  0.1024,    Adjusted R-squared:  0.04508 
F-statistic: 1.787 on 3 and 47 DF,  p-value: 0.1626

FaceChest

We originally defined FaceChest such that

  1. Face = eyes + mouth + chin
  2. Chest = upperchest + midchest + lowerchest

BUT. Chin is actually neck. It’s not even part of the face if you think about it. So I’m redefining FaceChest as:

  1. Face = forehead + eyes + mouth
  2. Chest = neck + upperchest + midchest + lowerchest

So let’s do this. Then see what’s happening across groups for FaceChest.

Cool. Next we’ll do error bar charts using the new FaceChest across groups.

facechest_info <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  group_by(maingroup, direction, participant) %>%
  summarise(facechest = mean(facechest, na.rm = TRUE)) %>%
  group_by(maingroup, direction) %>%
  summarise(mean = mean(facechest),
            sd = sd(facechest),
            n = n(),
            se = sd/sqrt(n))
ggplot(facechest_info, aes(x = maingroup, y = mean, fill = direction, color = direction)) +
  geom_point(stat = "identity", position = position_dodge(0.5), size = 2) + 
  geom_errorbar(aes(ymin = mean-se, ymax = mean+se), position = position_dodge(0.5), width = 0.3, size = 1) +
  labs(title = "FaceChest Ratio", subtitle = "Error bars represent SE", x = "", y = "facechest ratio") +
  scale_y_continuous(limits = c(-1,1)) + 
  geom_hline(yintercept = 0, linetype = "dotted")

Now let’s do the ANOVAs. Also skipping LSDs here.

  1. ANOVA with factors MainGroup & Direction.
Grouping rowwise data frame strips rowwise nature
                    Df Sum Sq Mean Sq F value Pr(>F)  
maingroup            3  1.317  0.4389   2.111 0.1040  
direction            1  0.712  0.7116   3.422 0.0674 .
maingroup:direction  3  0.283  0.0942   0.453 0.7157  
Residuals           95 19.754  0.2079                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. ANOVA with factor MainGroup, for Forward only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3  0.295 0.09847   0.608  0.613
Residuals   48  7.777 0.16202               
  1. ANOVA with factor MainGroup, for Reverse only.
            Df Sum Sq Mean Sq F value Pr(>F)
maingroup    3  1.279  0.4264   1.673  0.185
Residuals   47 11.977  0.2548               
  1. ANCOVA with factor Direction, and covariate AoASL and Age.
                    Df Sum Sq Mean Sq F value  Pr(>F)   
direction            1  0.736  0.7363   3.722 0.05667 . 
aoasl                1  0.014  0.0140   0.071 0.79077   
age                  1  2.218  2.2182  11.215 0.00116 **
direction:aoasl      1  0.024  0.0245   0.124 0.72574   
direction:age        1  0.162  0.1617   0.818 0.36814   
aoasl:age            1  0.026  0.0256   0.130 0.71972   
direction:aoasl:age  1  0.093  0.0934   0.472 0.49369   
Residuals           95 18.791  0.1978                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
  1. Regression with variables Age and AoASL, for Forward only

Call:
lm(formula = facechest ~ aoasl * age, data = filter(fc_data, 
    direction == "forward"))

Residuals:
    Min      1Q  Median      3Q     Max 
-1.1587 -0.1404  0.1393  0.2517  0.4754 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)  
(Intercept) -0.0308724  0.3874355  -0.080   0.9368  
aoasl        0.0306476  0.0277438   1.105   0.2748  
age          0.0207509  0.0112253   1.849   0.0707 .
aoasl:age   -0.0007246  0.0008600  -0.843   0.4037  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.3908 on 48 degrees of freedom
Multiple R-squared:  0.09183,   Adjusted R-squared:  0.03507 
F-statistic: 1.618 on 3 and 48 DF,  p-value: 0.1975
  1. Regression with variables Age and AoASL, for Reverse only

Call:
lm(formula = facechest ~ aoasl * age, data = filter(fc_data, 
    direction == "reversed"))

Residuals:
     Min       1Q   Median       3Q      Max 
-1.19830 -0.16427  0.08831  0.31808  0.62208 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.1552602  0.4895982  -0.317    0.753
aoasl        0.0004786  0.0350606   0.014    0.989
age          0.0204410  0.0141987   1.440    0.157
aoasl:age    0.0002265  0.0010868   0.208    0.836

Residual standard error: 0.4938 on 47 degrees of freedom
Multiple R-squared:  0.1355,    Adjusted R-squared:  0.08032 
F-statistic: 2.456 on 3 and 47 DF,  p-value: 0.07467

Eye Gaze & Performance Correlations

Next we’re going to correlate our eye gaze metrics (Eye, Mouth, Neck, and FaceChest) with lexical recall and gist. Okay! But remember we have a slightly smaller dataset here because we’ve excluded some participants for having bad eye data (but they had valid behavioral data so we kept them in the AoA-Performance correlations above).

We also removed gist_forward column.

eyeperf <- fulldata %>%
  filter(eye_exclude == FALSE) %>%
  select(participant, maingroup, hearing, direction, acc, gist, eyes, mouth, neck, facechest) %>%
  group_by(maingroup, participant, direction) %>%
  mutate(gist = mean(gist, na.rm = TRUE),
         lex = mean(acc, na.rm = TRUE),
         eyes = mean(eyes, na.rm = TRUE),
         mouth = mean(mouth, na.rm = TRUE),
         neck = mean(neck, na.rm = TRUE),
         facechest = mean(facechest, na.rm = TRUE)) %>%
  ungroup() %>%
  select(maingroup, participant, hearing, direction, gist, lex, eyes, mouth, neck, facechest) %>%
  distinct() %>%
  gather(metric, value, gist:facechest) %>%
  unite(metricvalue, c(metric, direction), sep = "_") %>%
  spread(metricvalue, value) %>%
  select(-participant, -maingroup) %>%
  select(hearing, gist_reversed, lex_forward, lex_reversed, eyes_forward, eyes_reversed,
         mouth_forward, mouth_reversed, neck_forward, neck_reversed, facechest_forward, facechest_reversed)
Grouping rowwise data frame strips rowwise nature
eyeperf_deaf <- eyeperf %>% filter(hearing == "Deaf") %>% select(-hearing)
eyeperf_hearing <- eyeperf %>% filter(hearing == "Hearing") %>% select(-hearing)
eyeperf_all <- eyeperf %>% select(-hearing)
# Correlations for Deaf
print("DEAF Correlations - Pearson's r")
[1] "DEAF Correlations - Pearson's r"
#corstarsl(lexgist_deaf)
Hmisc::rcorr(as.matrix(eyeperf_deaf))$r
                   gist_reversed lex_forward lex_reversed eyes_forward eyes_reversed mouth_forward
gist_reversed         1.00000000  -0.1103272   0.30316901  -0.06319147    0.02254098     0.1399812
lex_forward          -0.11032724   1.0000000   0.12103733   0.19560269    0.19460939     0.1127365
lex_reversed          0.30316901   0.1210373   1.00000000  -0.09834590   -0.07989090     0.1398463
eyes_forward         -0.06319147   0.1956027  -0.09834590   1.00000000    0.53012073    -0.4038958
eyes_reversed         0.02254098   0.1946094  -0.07989090   0.53012073    1.00000000    -0.1084938
mouth_forward         0.13998124   0.1127365   0.13984634  -0.40389580   -0.10849377     1.0000000
mouth_reversed        0.06590948   0.1511229   0.11828493  -0.18798503   -0.45147687     0.6487395
neck_forward         -0.10845388  -0.2818219  -0.06254636  -0.40213531   -0.32258892    -0.6652489
neck_reversed        -0.07553297  -0.2951812  -0.01236971  -0.29756692   -0.42235607    -0.5483285
facechest_forward     0.10233361   0.2796232   0.05057043   0.37868726    0.32650983     0.6918055
facechest_reversed    0.08644924   0.3039166   0.03749677   0.28118142    0.43328831     0.5811273
                   mouth_reversed neck_forward neck_reversed facechest_forward facechest_reversed
gist_reversed          0.06590948  -0.10845388   -0.07553297        0.10233361         0.08644924
lex_forward            0.15112290  -0.28182188   -0.29518121        0.27962315         0.30391663
lex_reversed           0.11828493  -0.06254636   -0.01236971        0.05057043         0.03749677
eyes_forward          -0.18798503  -0.40213531   -0.29756692        0.37868726         0.28118142
eyes_reversed         -0.45147687  -0.32258892   -0.42235607        0.32650983         0.43328831
mouth_forward          0.64873952  -0.66524893   -0.54832852        0.69180554         0.58112735
mouth_reversed         1.00000000  -0.52286172   -0.59771758        0.49638316         0.59842563
neck_forward          -0.52286172   1.00000000    0.82565296       -0.99141806        -0.83648926
neck_reversed         -0.59771758   0.82565296    1.00000000       -0.79461950        -0.99196124
facechest_forward      0.49638316  -0.99141806   -0.79461950        1.00000000         0.81218421
facechest_reversed     0.59842563  -0.83648926   -0.99196124        0.81218421         1.00000000
print("DEAF Correlations - P-values")
[1] "DEAF Correlations - P-values"
Hmisc::rcorr(as.matrix(eyeperf_deaf))$P
                   gist_reversed lex_forward lex_reversed eyes_forward eyes_reversed mouth_forward
gist_reversed                 NA   0.5762360    0.1168234  0.749383585   0.909355255  4.774249e-01
lex_forward            0.5762360          NA    0.5395250  0.309208485   0.321023718  5.603910e-01
lex_reversed           0.1168234   0.5395250           NA  0.618567671   0.686127314  4.778537e-01
eyes_forward           0.7493836   0.3092085    0.6185677           NA   0.003712324  2.978758e-02
eyes_reversed          0.9093553   0.3210237    0.6861273  0.003712324            NA  5.826299e-01
mouth_forward          0.4774249   0.5603910    0.4778537  0.029787577   0.582629892            NA
mouth_reversed         0.7389667   0.4427051    0.5488533  0.338088512   0.015882316  1.883815e-04
neck_forward           0.5827693   0.1385770    0.7518624  0.030576543   0.094080464  8.235941e-05
neck_reversed          0.7024562   0.1272716    0.9501866  0.124081940   0.025159368  2.519354e-03
facechest_forward      0.6043367   0.1418142    0.7982931  0.042791159   0.089925263  3.228725e-05
facechest_reversed     0.6618134   0.1158789    0.8497523  0.147206817   0.021262891  1.183228e-03
                   mouth_reversed neck_forward neck_reversed facechest_forward facechest_reversed
gist_reversed        0.7389666674 5.827693e-01  7.024562e-01      6.043367e-01       6.618134e-01
lex_forward          0.4427050811 1.385770e-01  1.272716e-01      1.418142e-01       1.158789e-01
lex_reversed         0.5488532932 7.518624e-01  9.501866e-01      7.982931e-01       8.497523e-01
eyes_forward         0.3380885118 3.057654e-02  1.240819e-01      4.279116e-02       1.472068e-01
eyes_reversed        0.0158823163 9.408046e-02  2.515937e-02      8.992526e-02       2.126289e-02
mouth_forward        0.0001883815 8.235941e-05  2.519354e-03      3.228725e-05       1.183228e-03
mouth_reversed                 NA 4.307483e-03  7.826592e-04      7.216113e-03       7.685904e-04
neck_forward         0.0043074830           NA  6.358068e-08      0.000000e+00       2.946681e-08
neck_reversed        0.0007826592 6.358068e-08            NA      4.429714e-07       0.000000e+00
facechest_forward    0.0072161132 0.000000e+00  4.429714e-07                NA       1.541998e-07
facechest_reversed   0.0007685904 2.946681e-08  0.000000e+00      1.541998e-07                 NA
cat(paste("","\n",""))
# Correlations for Hearing
print("HEARING Correlations - Pearson's r")
[1] "HEARING Correlations - Pearson's r"
#corstarsl(lexgist_hearing)
Hmisc::rcorr(as.matrix(eyeperf_hearing))$r
                   gist_reversed lex_forward lex_reversed eyes_forward eyes_reversed mouth_forward
gist_reversed        1.000000000  0.32119471   0.61989301   -0.2017262  -0.003896097   -0.02203918
lex_forward          0.321194708  1.00000000   0.23279549   -0.2064124  -0.043613102    0.04471777
lex_reversed         0.619893014  0.23279549   1.00000000   -0.0936432  -0.128554240   -0.12913127
eyes_forward        -0.201726153 -0.20641239  -0.09364320    1.0000000   0.794651926   -0.75736409
eyes_reversed       -0.003896097 -0.04361310  -0.12855424    0.7946519   1.000000000   -0.53289974
mouth_forward       -0.022039175  0.04471777  -0.12913127   -0.7573641  -0.532899737    1.00000000
mouth_reversed      -0.057827983 -0.08355581   0.01769962   -0.4947033  -0.608459473    0.73505580
neck_forward         0.367403537  0.36551589   0.36037686   -0.5478414  -0.524459183   -0.08094060
neck_reversed        0.223993644  0.27462074   0.24863580   -0.5678435  -0.667670012    0.06470188
facechest_forward   -0.340341955 -0.28030962  -0.29633671    0.5328411   0.513289094    0.14471392
facechest_reversed  -0.163039193 -0.15098999  -0.19097045    0.5098403   0.602644563    0.05395970
                   mouth_reversed neck_forward neck_reversed facechest_forward facechest_reversed
gist_reversed         -0.05782798    0.3674035    0.22399364        -0.3403420         -0.1630392
lex_forward           -0.08355581    0.3655159    0.27462074        -0.2803096         -0.1509900
lex_reversed           0.01769962    0.3603769    0.24863580        -0.2963367         -0.1909705
eyes_forward          -0.49470326   -0.5478414   -0.56784350         0.5328411          0.5098403
eyes_reversed         -0.60845947   -0.5244592   -0.66767001         0.5132891          0.6026446
mouth_forward          0.73505580   -0.0809406    0.06470188         0.1447139          0.0539597
mouth_reversed         1.00000000   -0.0758556   -0.09060995         0.1957614          0.2372879
neck_forward          -0.07585560    1.0000000    0.76188785        -0.9424162         -0.7260022
neck_reversed         -0.09060995    0.7618878    1.00000000        -0.7833102         -0.9351352
facechest_forward      0.19576141   -0.9424162   -0.78331023         1.0000000          0.8350726
facechest_reversed     0.23728788   -0.7260022   -0.93513525         0.8350726          1.0000000
print("HEARING Correlations - P-values")
[1] "HEARING Correlations - P-values"
Hmisc::rcorr(as.matrix(eyeperf_hearing))$P
                   gist_reversed lex_forward lex_reversed eyes_forward eyes_reversed mouth_forward
gist_reversed                 NA  0.13506603  0.001604978 3.559903e-01  9.859236e-01  9.204923e-01
lex_forward          0.135066028          NA  0.285087190 3.446869e-01  8.433655e-01  8.394476e-01
lex_reversed         0.001604978  0.28508719           NA 6.708451e-01  5.588320e-01  5.570536e-01
eyes_forward         0.355990294  0.34468693  0.670845077           NA  5.929025e-06  2.859607e-05
eyes_reversed        0.985923639  0.84336552  0.558831962 5.929025e-06            NA  8.840848e-03
mouth_forward        0.920492311  0.83944758  0.557053614 2.859607e-05  8.840848e-03            NA
mouth_reversed       0.793254811  0.70466052  0.936112687 1.640479e-02  2.065194e-03  6.461917e-05
neck_forward         0.084589444  0.08632257  0.091175442 6.807338e-03  1.019589e-02  7.135195e-01
neck_reversed        0.304204139  0.20474801  0.252624987 4.707219e-03  4.996113e-04  7.692911e-01
facechest_forward    0.112046749  0.19514544  0.169752614 8.849713e-03  1.224782e-02  5.100229e-01
facechest_reversed   0.457300336  0.49164189  0.382738792 1.294574e-02  2.339301e-03  8.068219e-01
                   mouth_reversed neck_forward neck_reversed facechest_forward facechest_reversed
gist_reversed        7.932548e-01 8.458944e-02  3.042041e-01      1.120467e-01       4.573003e-01
lex_forward          7.046605e-01 8.632257e-02  2.047480e-01      1.951454e-01       4.916419e-01
lex_reversed         9.361127e-01 9.117544e-02  2.526250e-01      1.697526e-01       3.827388e-01
eyes_forward         1.640479e-02 6.807338e-03  4.707219e-03      8.849713e-03       1.294574e-02
eyes_reversed        2.065194e-03 1.019589e-02  4.996113e-04      1.224782e-02       2.339301e-03
mouth_forward        6.461917e-05 7.135195e-01  7.692911e-01      5.100229e-01       8.068219e-01
mouth_reversed                 NA 7.308466e-01  6.809521e-01      3.706863e-01       2.756272e-01
neck_forward         7.308466e-01           NA  2.398635e-05      1.861311e-11       8.797435e-05
neck_reversed        6.809521e-01 2.398635e-05            NA      9.878377e-06       6.290368e-11
facechest_forward    3.706863e-01 1.861311e-11  9.878377e-06                NA       7.177950e-07
facechest_reversed   2.756272e-01 8.797435e-05  6.290368e-11      7.177950e-07                 NA
cat(paste("","\n",""))
# Correlations for All
print("ALL Correlations - Pearson's r")
[1] "ALL Correlations - Pearson's r"
#corstarsl(lexgist_all)
Hmisc::rcorr(as.matrix(eyeperf_all))$r
                   gist_reversed  lex_forward lex_reversed eyes_forward eyes_reversed mouth_forward
gist_reversed       1.0000000000  0.157367334   0.44831455   -0.1583381  -0.033147462    0.12706694
lex_forward         0.1573673338  1.000000000   0.23866823   -0.1346806  -0.007873518    0.11668780
lex_reversed        0.4483145475  0.238668233   1.00000000   -0.1345993  -0.140279055    0.05451585
eyes_forward       -0.1583380550 -0.134680599  -0.13459931    1.0000000   0.706692934   -0.62307096
eyes_reversed      -0.0331474617 -0.007873518  -0.14027905    0.7066929   1.000000000   -0.36512721
mouth_forward       0.1270669401  0.116687804   0.05451585   -0.6230710  -0.365127206    1.00000000
mouth_reversed      0.1034677997  0.081888258   0.14056188   -0.3857141  -0.544273436    0.70370090
neck_forward        0.0342302844  0.051669102   0.10643122   -0.4273281  -0.388957769   -0.40481210
neck_reversed      -0.0002581948  0.003536053   0.07954131   -0.3926680  -0.503218710   -0.28553602
facechest_forward  -0.0335624404 -0.031654894  -0.09553912    0.4281833   0.402936906    0.43687293
facechest_reversed  0.0425947122  0.063717648  -0.02840233    0.3631589   0.482238919    0.34413567
                   mouth_reversed neck_forward neck_reversed facechest_forward facechest_reversed
gist_reversed          0.10346780   0.03423028 -0.0002581948       -0.03356244         0.04259471
lex_forward            0.08188826   0.05166910  0.0035360528       -0.03165489         0.06371765
lex_reversed           0.14056188   0.10643122  0.0795413107       -0.09553912        -0.02840233
eyes_forward          -0.38571414  -0.42732805 -0.3926679790        0.42818332         0.36315894
eyes_reversed         -0.54427344  -0.38895777 -0.5032187104        0.40293691         0.48223892
mouth_forward          0.70370090  -0.40481210 -0.2855360210        0.43687293         0.34413567
mouth_reversed         1.00000000  -0.31946859 -0.3897527158        0.35403353         0.45460728
neck_forward          -0.31946859   1.00000000  0.7993095517       -0.96537608        -0.76219910
neck_reversed         -0.38975272   0.79930955  1.0000000000       -0.78893071        -0.95769274
facechest_forward      0.35403353  -0.96537608 -0.7889307141        1.00000000         0.81137252
facechest_reversed     0.45460728  -0.76219910 -0.9576927423        0.81137252         1.00000000
print("ALL Correlations - P-values")
[1] "ALL Correlations - P-values"
Hmisc::rcorr(as.matrix(eyeperf_all))$P
                   gist_reversed lex_forward lex_reversed eyes_forward eyes_reversed mouth_forward
gist_reversed                 NA  0.27008993 0.0009694904 2.671087e-01  8.173808e-01  3.742438e-01
lex_forward         0.2700899346          NA 0.0916709472 3.411308e-01  9.562699e-01  4.100460e-01
lex_reversed        0.0009694904  0.09167095           NA 3.463483e-01  3.261871e-01  7.039810e-01
eyes_forward        0.2671087463  0.34113082 0.3463483357           NA  6.830266e-09  8.097570e-07
eyes_reversed       0.8173807987  0.95626990 0.3261870511 6.830266e-09            NA  8.425391e-03
mouth_forward       0.3742437833  0.41004603 0.7039809873 8.097570e-07  8.425391e-03            NA
mouth_reversed      0.4699673532  0.56782200 0.3252028385 5.184763e-03  3.651371e-05  8.423032e-09
neck_forward        0.8115222617  0.71602452 0.4572739900 1.579676e-03  4.789468e-03  2.913237e-03
neck_reversed       0.9985652716  0.98035289 0.5790064531 4.369926e-03  1.673548e-04  4.224662e-02
facechest_forward   0.8151343981  0.82371178 0.5048365664 1.542092e-03  3.372262e-03  1.203117e-03
facechest_reversed  0.7666339865  0.65689363 0.8431666495 8.811831e-03  3.391156e-04  1.340835e-02
                   mouth_reversed neck_forward neck_reversed facechest_forward facechest_reversed
gist_reversed        4.699674e-01 8.115223e-01  9.985653e-01      8.151344e-01       7.666340e-01
lex_forward          5.678220e-01 7.160245e-01  9.803529e-01      8.237118e-01       6.568936e-01
lex_reversed         3.252028e-01 4.572740e-01  5.790065e-01      5.048366e-01       8.431666e-01
eyes_forward         5.184763e-03 1.579676e-03  4.369926e-03      1.542092e-03       8.811831e-03
eyes_reversed        3.651371e-05 4.789468e-03  1.673548e-04      3.372262e-03       3.391156e-04
mouth_forward        8.423032e-09 2.913237e-03  4.224662e-02      1.203117e-03       1.340835e-02
mouth_reversed                 NA 2.230426e-02  4.696719e-03      1.081053e-02       8.043284e-04
neck_forward         2.230426e-02           NA  2.037925e-12      0.000000e+00       8.169354e-11
neck_reversed        4.696719e-03 2.037925e-12            NA      6.159073e-12       0.000000e+00
facechest_forward    1.081053e-02 0.000000e+00  6.159073e-12                NA       5.182521e-13
facechest_reversed   8.043284e-04 8.169354e-11  0.000000e+00      5.182521e-13                 NA

I’m also including nicely formatted tables with *** indicators of significance for quick referencing. Order: Deaf, Hearing, All.

corstarsl(eyeperf_deaf)
corstarsl(eyeperf_hearing)
corstarsl(eyeperf_all)

And the correlation table.

ggpairs(eyeperf, columns = c(2:11), aes(color = hearing))

 plot: [1,1] [=---------------------------------------------------------------------------]  1% est: 0s 
 plot: [1,2] [==--------------------------------------------------------------------------]  2% est: 8s 
 plot: [1,3] [==--------------------------------------------------------------------------]  3% est: 9s 
 plot: [1,4] [===-------------------------------------------------------------------------]  4% est:11s 
 plot: [1,5] [====------------------------------------------------------------------------]  5% est:12s 
 plot: [1,6] [=====-----------------------------------------------------------------------]  6% est:13s 
 plot: [1,7] [=====-----------------------------------------------------------------------]  7% est:13s 
 plot: [1,8] [======----------------------------------------------------------------------]  8% est:12s 
 plot: [1,9] [=======---------------------------------------------------------------------]  9% est:12s 
 plot: [1,10] [========-------------------------------------------------------------------] 10% est:12s 
 plot: [2,1] [========--------------------------------------------------------------------] 11% est:12s 
 plot: [2,2] [=========-------------------------------------------------------------------] 12% est:12s 
 plot: [2,3] [==========------------------------------------------------------------------] 13% est:12s 
 plot: [2,4] [===========-----------------------------------------------------------------] 14% est:12s 
 plot: [2,5] [===========-----------------------------------------------------------------] 15% est:12s 
 plot: [2,6] [============----------------------------------------------------------------] 16% est:11s 
 plot: [2,7] [=============---------------------------------------------------------------] 17% est:11s 
 plot: [2,8] [==============--------------------------------------------------------------] 18% est:11s 
 plot: [2,9] [==============--------------------------------------------------------------] 19% est:10s 
 plot: [2,10] [===============------------------------------------------------------------] 20% est:10s 
 plot: [3,1] [================------------------------------------------------------------] 21% est:10s 
 plot: [3,2] [=================-----------------------------------------------------------] 22% est:10s 
 plot: [3,3] [=================-----------------------------------------------------------] 23% est:10s 
 plot: [3,4] [==================----------------------------------------------------------] 24% est:10s 
 plot: [3,5] [===================---------------------------------------------------------] 25% est:10s 
 plot: [3,6] [====================--------------------------------------------------------] 26% est: 9s 
 plot: [3,7] [=====================-------------------------------------------------------] 27% est: 9s 
 plot: [3,8] [=====================-------------------------------------------------------] 28% est: 9s 
 plot: [3,9] [======================------------------------------------------------------] 29% est: 9s 
 plot: [3,10] [======================-----------------------------------------------------] 30% est: 9s 
 plot: [4,1] [========================----------------------------------------------------] 31% est: 9s 
 plot: [4,2] [========================----------------------------------------------------] 32% est: 8s 
 plot: [4,3] [=========================---------------------------------------------------] 33% est: 8s 
 plot: [4,4] [==========================--------------------------------------------------] 34% est: 8s 
 plot: [4,5] [===========================-------------------------------------------------] 35% est: 8s 
 plot: [4,6] [===========================-------------------------------------------------] 36% est: 8s 
 plot: [4,7] [============================------------------------------------------------] 37% est: 8s 
 plot: [4,8] [=============================-----------------------------------------------] 38% est: 8s 
 plot: [4,9] [==============================----------------------------------------------] 39% est: 8s 
 plot: [4,10] [==============================---------------------------------------------] 40% est: 8s 
 plot: [5,1] [===============================---------------------------------------------] 41% est: 7s 
 plot: [5,2] [================================--------------------------------------------] 42% est: 7s 
 plot: [5,3] [=================================-------------------------------------------] 43% est: 7s 
 plot: [5,4] [=================================-------------------------------------------] 44% est: 7s 
 plot: [5,5] [==================================------------------------------------------] 45% est: 7s 
 plot: [5,6] [===================================-----------------------------------------] 46% est: 7s 
 plot: [5,7] [====================================----------------------------------------] 47% est: 7s 
 plot: [5,8] [====================================----------------------------------------] 48% est: 6s 
 plot: [5,9] [=====================================---------------------------------------] 49% est: 6s 
 plot: [5,10] [======================================-------------------------------------] 50% est: 6s 
 plot: [6,1] [=======================================-------------------------------------] 51% est: 6s 
 plot: [6,2] [========================================------------------------------------] 52% est: 6s 
 plot: [6,3] [========================================------------------------------------] 53% est: 6s 
 plot: [6,4] [=========================================-----------------------------------] 54% est: 6s 
 plot: [6,5] [==========================================----------------------------------] 55% est: 6s 
 plot: [6,6] [===========================================---------------------------------] 56% est: 5s 
 plot: [6,7] [===========================================---------------------------------] 57% est: 5s 
 plot: [6,8] [============================================--------------------------------] 58% est: 5s 
 plot: [6,9] [=============================================-------------------------------] 59% est: 5s 
 plot: [6,10] [=============================================------------------------------] 60% est: 5s 
 plot: [7,1] [==============================================------------------------------] 61% est: 5s 
 plot: [7,2] [===============================================-----------------------------] 62% est: 5s 
 plot: [7,3] [================================================----------------------------] 63% est: 5s 
 plot: [7,4] [=================================================---------------------------] 64% est: 5s 
 plot: [7,5] [=================================================---------------------------] 65% est: 4s 
 plot: [7,6] [==================================================--------------------------] 66% est: 4s 
 plot: [7,7] [===================================================-------------------------] 67% est: 4s 
 plot: [7,8] [====================================================------------------------] 68% est: 4s 
 plot: [7,9] [====================================================------------------------] 69% est: 4s 
 plot: [7,10] [====================================================-----------------------] 70% est: 4s 
 plot: [8,1] [======================================================----------------------] 71% est: 4s 
 plot: [8,2] [=======================================================---------------------] 72% est: 4s 
 plot: [8,3] [=======================================================---------------------] 73% est: 3s 
 plot: [8,4] [========================================================--------------------] 74% est: 3s 
 plot: [8,5] [=========================================================-------------------] 75% est: 3s 
 plot: [8,6] [==========================================================------------------] 76% est: 3s 
 plot: [8,7] [===========================================================-----------------] 77% est: 3s 
 plot: [8,8] [===========================================================-----------------] 78% est: 3s 
 plot: [8,9] [============================================================----------------] 79% est: 3s 
 plot: [8,10] [============================================================---------------] 80% est: 3s 
 plot: [9,1] [==============================================================--------------] 81% est: 2s 
 plot: [9,2] [==============================================================--------------] 82% est: 2s 
 plot: [9,3] [===============================================================-------------] 83% est: 2s 
 plot: [9,4] [================================================================------------] 84% est: 2s 
 plot: [9,5] [=================================================================-----------] 85% est: 2s 
 plot: [9,6] [=================================================================-----------] 86% est: 2s 
 plot: [9,7] [==================================================================----------] 87% est: 2s 
 plot: [9,8] [===================================================================---------] 88% est: 2s 
 plot: [9,9] [====================================================================--------] 89% est: 1s 
 plot: [9,10] [====================================================================-------] 90% est: 1s 
 plot: [10,1] [====================================================================-------] 91% est: 1s 
 plot: [10,2] [=====================================================================------] 92% est: 1s 
 plot: [10,3] [======================================================================-----] 93% est: 1s 
 plot: [10,4] [======================================================================-----] 94% est: 1s 
 plot: [10,5] [=======================================================================----] 95% est: 1s 
 plot: [10,6] [========================================================================---] 96% est: 1s 
 plot: [10,7] [=========================================================================--] 97% est: 0s 
 plot: [10,8] [==========================================================================-] 98% est: 0s 
 plot: [10,9] [==========================================================================-] 99% est: 0s 
 plot: [10,10] [==========================================================================]100% est: 0s 
                                                                                                        

Heat Maps

And finally, we’re going to do heat maps.

eyegaze_heat <- fulldata %>%
  ungroup() %>%
  filter(eye_exclude == FALSE) %>%
  select(id:direction, belly, lowerchest, midchest, upperchest, neck, mouth, eyes, forehead) %>%
  gather(aoi, percent, belly:forehead) %>%
  group_by(maingroup, participant, direction, aoi) %>%
  summarise(percent = mean(percent, na.rm=TRUE)) %>%
  group_by(maingroup,direction,aoi) %>%
  summarise(percent = mean(percent, na.rm=TRUE)) %>%
  ungroup() %>%
  filter(!is.na(aoi)) %>%
  mutate(aoi = factor(aoi,levels=c("belly","lowerchest","midchest",
                                   "upperchest","neck","mouth","eyes","forehead")))
eyegaze_heat_all <- fulldata %>%
  ungroup() %>%
  filter(eye_exclude == FALSE) %>%
  select(id:direction, belly, lowerchest, midchest, upperchest, neck, mouth, eyes, forehead) %>%
  gather(aoi, percent, belly:forehead) %>%
  group_by(maingroup,participant,direction,aoi) %>%
  dplyr::summarize(percent = mean(percent, na.rm=TRUE)) %>%
  group_by(maingroup,direction,aoi) %>%
  dplyr::summarize(percent = mean(percent, na.rm=TRUE)) %>%
  group_by(maingroup,aoi) %>%
  dplyr::summarize(percent = mean(percent, na.rm=TRUE)) %>%
  ungroup() %>%
  filter(!is.na(aoi)) %>%
  mutate(aoi = factor(aoi,levels=c("belly","lowerchest","midchest",
                                   "upperchest","neck","mouth","eyes","forehead")))
ggplot(eyegaze_heat, aes(x = maingroup, y = aoi)) +
  geom_tile(aes(fill=percent),color="lightgray",na.rm=TRUE) + 
#  scale_fill_gradient(low = "lightblue",high = "steelblue") +
#  scale_fill_distiller(type="div", palette = "RdYlBu") +
  scale_fill_viridis(option = "viridis", direction=-1, limits = c(0,.75)) +
  theme(axis.text.x=element_text(angle=45,hjust=1)) + facet_grid(. ~ direction) +
  ylab("") + xlab("") + ggtitle("Eye Gaze Heat Map, by Direction")

ggplot(eyegaze_heat_all, aes(x = maingroup, y = aoi)) +
  geom_tile(aes(fill=percent),color="lightgray",na.rm=TRUE) + 
#  scale_fill_gradient(low = "lightblue",high = "steelblue") +
#  scale_fill_distiller(type="div", palette = "RdYlBu") +
  scale_fill_viridis(option = "viridis", direction=-1, limits = c(0,.75)) +
  theme(axis.text.x=element_text(angle=45,hjust=1)) +
  ylab("") + xlab("") + ggtitle("Eye Gaze Heat Map (Direction Collapsed)")

Summary

Below are the p-values from the ANOVAs with 4 MainGroups. I never included Age as a covariate because it never improved the model. I included all ANOVAs for Gist and Lex Recall, and ANOVAs for any eye AOI or ratio was included only if either maingroup or direction was significant. Deafearly-Deaflate shows the LSD p-value for that comparison.

results1 <- structure(list(model = c("gist-maingroup-both", "gist-maingroup-fw", 
"gist-maingroup-rv", "lexrecall-maingroup-both", "lexrecall-maingroup-fw", 
"lexrecall-maingroup-rv", "mouth-maingroup-both", "upperchest-maingroup-both", 
"upperchest-maingroup-rv", "facechest-maingroup-both", "moutheye-maingroup-both"
), maingroup = c(0, 0, 0.01, 0, 0.04, 0.02, 0.06, 0, 0.01, 0.1, 
0.05), direction = c(0, NA, NA, 0, NA, NA, 0.06, 0.16, NA, 0.07, 
0.48), `deafearly-deaflate` = c(0.1, 0.69, 0.02, 0.11, 0.95, 
0.06, 0.38, 0.94, 0.52, 0.08, 0.68)), .Names = c("model", "maingroup", 
"direction", "deafearly-deaflate"), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -11L))
results1

And below are the p-values from the ANCOVAs with Hearing & AoASL. I included all ANCOVAs for Gist and Lex Recall, and ANCOVAs for any eye AOI or ratio was included only if any main factor was significant. LSD comparisons are not needed because there’s only 2 levels in each group!

results2 <- structure(list(model = c("gist-both", "gist-fw", "gist-rv", "lex-both", 
"lex-fw", "lex-rv", "forehead-fw", "mouth-both", "mouth-rv", 
"upperchest-both", "upperchest-rv", "facechest-both", "moutheye-both"
), hearing = c(0, 0.00, 0.01, 0.01, 0.22, 0.03, 0.06, 0.01, 
0.04, 0.01, 0.01, 0.35, 0.07), direction = c(0, NA, NA, 0, NA, 
NA, NA, 0.05, NA, 0.21, NA, 0.05, 0.52), aoasl = c(0.22, 0.77, 
0.19, 0.56, 0.58, 0.25, 0.08, 0.06, 0.12, 0.68, 0.95, 0.12, 0.44
), age = c(0.08, 0.01, 0.86, 0.09, 0.02, 0.7, 0.68, 0.28, 0.5, 
0.02, 0.08, 0.00, 0.21)), .Names = c("model", "hearing", "direction", 
"aoasl", "age"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-13L))
results2

Finally, the correlations for Deaf and Hearing separately are not significant. But there are significant correlations across all participants. I worry it is caused by HearingNovice, though…

results3 <- tribble(
  ~ metric, ~ AoASLcorrelationRvalue, ~ Pvalue,
  "gist-fw", -0.32, 0.019,
  "gist-rv", -0.39, 0.004,
  "lex-fw", -0.08, 0.567,
  "lex-rv", -0.34, 0.014
)
results3

Ternary Plots

Let’s make triangle plots. “What?” you say. Read on.

library(ggtern)
fulldata %>% 
  ggtern(aes(x = eyes, y = mouth, z = neck)) + facet_grid(direction ~ maingroup) + stat_density_tern(geom='polygon', aes(fill=..level..), bins=4) + geom_point(color = "white", alpha = 0.5) + theme_bw()

fulldata %>% 
  ggtern(aes(x = eyes, y = mouth, z = neck)) + facet_grid(direction ~ maingroup) + geom_confidence_tern(breaks = c(.5), color = "red") + geom_point() + theme_bw()

Rain’s Notes

About Adults:

-I think I want to write it up as an ANCOVA, with direction included. And LSD comparisons instead of Tukey. (I will do my own corrections) -You often have one liners summarizing results, in all tabs, those are nice, keep them coming. -(If you have reasons to present anything other than the ANCOVA, put that in your results tab)

I think if we do it this way then we get a really important story to tell: That the critical AoA cutoff is below 4 vs above 4 years of age (two groups 0-4 vs 4-13). This suggest early ASL is important.

LS0tCnRpdGxlOiAiVGhlIExhc3QgRGF0YSBBbmFseXNpcyB0byBSdWxlIFRoZW0gQWxsPyAoc3R1ZHkxYWR1bHRzKSIKYXV0aG9yOiAiQWRhbSBTdG9uZSwgUGhEIgpkYXRlOiAnYHIgZm9ybWF0KFN5cy5EYXRlKCksICIlbS0lZC0lWSIpYCcKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHRoZW1lOiBwYXBlcgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgojIFB1dHRpbmcgSXQgQWxsIEJhY2sgVG9nZXRoZXIKClRocm91Z2hvdXQgYWxsIHRoZSBkYXRhIGFuYWx5c2lzIHdlJ3ZlIGRvbmUsIHRoZSBkYXRhc2V0cyBoYXZlIGJlY29tZSBtb3JlIGZyYWdtZW50ZWQgLSBsZXhpY2FsIHJlY2FsbCwgZ2lzdCwgYW5kIGV5ZSB0cmFja2luZyBkYXRhc2V0cy4gSSB3YW50IHRvIHB1dCB0aGVtIGFsbCB0b2dldGhlciBpbiBvbmUgd2hvbGUgZGF0YXNldCBhZ2FpbiBzbyB3ZSBjYW4gcGVyZm9ybSBzb21lIGFuYWx5c2VzIG1vcmUgZWZmaWNpZW50bHkgKHBhcnRpY3VsYXJseSBjb3JyZWxhdGlvbnMpLiBUaGUgb25seSB0aGluZyBJIG5lZWQgdG8gcmVtZW1iZXIgaXMgd2UnbGwgaGF2ZSBhIG5ldyBjb2x1bW4gY2FsbGVkIGBleWVfZXhjbHVkZWAgYW5kIGlmIGl0IGlzIHNldCB0byBgVFJVRWAgaXQgbWVhbnMgd2UgY2FuJ3QgaW5jbHVkZSB0aGF0IHJvdyBpbiBhbnkgYW5hbHlzaXMgcmVsYXRpbmcgdG8gZXllIGdhemUgKHVzdWFsbHkgYmVjYXVzZSB0aGF0IHRyaWFsIHdhcyBsZXNzIHRoYW4gMjUlIGxvb2tpbmcpLiAKCmBgYHtyIHNtYXNoIGRhdGEgdG9nZXRoZXIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgTGlicmFyaWVzCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkobG1lclRlc3QpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkoYWdyaWNvbGFlKSAKbGlicmFyeShHR2FsbHkpCgojIExvYWQgbGV4IGFuZCBleWUgZGF0YQpjbGVhbmxleGRhdGEgPC0gcmVhZF9jc3YoImNsZWFuZGF0YS5jc3YiKSAlPiUKICBzZWxlY3QoLShmb3JlaGVhZDp0b3RhbCkpCgpjbGVhbmV5ZWRhdGEgPC0gcmVhZF9jc3YoImNsZWFucGVyY2VudGRhdGEuY3N2IikgJT4lCiAgc3ByZWFkKGFvaSxwZXJjZW50KSAlPiUKICBhZGRfY29sdW1uKGV5ZV9leGNsdWRlID0gRkFMU0UpCgojIFdoYXQgcm93cyB3ZXJlIHJlbW92ZWQgZnJvbSB0aGUgZXllIGRhdGEgYmFjayBpbiAwM2V5ZWdhemU/IExldCdzIGFkZCBiYWNrIGluCiMgV2l0aCBhIG5ldyBjb2x1bW4gLSBleWVfZXhjbHVkZQpyZW1vdmVkIDwtIGFudGlfam9pbihjbGVhbmxleGRhdGEsIGNsZWFuZXllZGF0YSkgJT4lCiAgYWRkX2NvbHVtbihleWVfZXhjbHVkZSA9IFRSVUUpCmV5ZWxleGRhdGEgPC0gYmluZF9yb3dzKGNsZWFuZXllZGF0YSwgcmVtb3ZlZCkKCiMgTG9hZCBnaXN0IGRhdGEKZ2lzdCA8LSByZWFkX2NzdignZ2lzdF9pbmRpdi5jc3YnLCBjb2xfdHlwZXMgPSBjb2xzKAogIHBhcnRpY2lwYW50ID0gY29sX2NoYXJhY3RlcigpLAogIGdpc3QuZncxID0gY29sX2ludGVnZXIoKSwKICBnaXN0LnJ2MiA9IGNvbF9pbnRlZ2VyKCksCiAgZ2lzdC5mdzMgPSBjb2xfaW50ZWdlcigpLAogIGdpc3QucnY0ID0gY29sX2ludGVnZXIoKQopKSAlPiUKICBnYXRoZXIodmlkZW8sIGdpc3QsIGdpc3QuZncxOmdpc3QucnY0KSAlPiUKICBtdXRhdGUodmlkZW8gPSBzdHJfc3ViKHZpZGVvLDYsOCkpCgojIFByZXN0bywgb3VyIGZ1bGwgcmV1bmlmaWVkIGRhdGFzZXQgLSAnZnVsbGRhdGEnCiMgQnV0IEkgd2FudCB0byByZW1vdmUgY29sdW1ucyBJIGRvbid0IHdhbnQgYW55bW9yZSBhbmQgd2lsbCByZWNhbGN1bGF0ZSBsYXRlcgpmdWxsZGF0YSA8LSBsZWZ0X2pvaW4oZXllbGV4ZGF0YSwgZ2lzdCkgJT4lCiAgc2VsZWN0KC1tb3V0aGV5ZSwgLWZhY2VjaGVzdCwgLWZhY2UsIC1jaGVzdCkKYGBgCgojIEdyb3VwIENoYW5nZXMgYW5kIFBhcnRpY2lwYW50IFRhYmxlcwoKV2UgaGF2ZSBzb21lIGNoYW5nZXMgdG8gbWFrZSB0byB0aGUgZ3JvdXBzLiBGaXJzdCwgZml4IEpvc2ggYXMgbGVhcm5pbmcgQVNMIHdoZW4gaGUgd2FzIDYuIE5leHQsIGRyb3AgdGhlIERlYWZOYXRpdmUgR3JvdXAgYW5kIHJlY2xhc3NpZnkgYWxsIHdobyBsZWFybmVkIEFTTCA8IDMuOSBhcyBEZWFmRWFybHkgYW5kIEFTTCA9PiA0LjAgYXMgRGVhZkxhdGUuIAoKYGBge3IgZ3JvdXBzIGFuZCBwYXJ0aWNpcGFudCB0YWJsZXN9CiMgQ2hhbmdlIEpvc2gncyBBb0FTTCB0byA2CmZ1bGxkYXRhIDwtIGZ1bGxkYXRhICU+JQogIG11dGF0ZShhb2FzbCA9IGFzLmRvdWJsZShhb2FzbCkpICU+JQogIG11dGF0ZShhb2FzbCA9IGNhc2Vfd2hlbigKICAgIHBhcnRpY2lwYW50ID09ICJKb3NoIiB+IDYsCiAgICBUUlVFIH4gYW9hc2wKICApKQoKIyBSZWNsYXNzaWZ5IEdyb3VwcwpmdWxsZGF0YSA8LSBmdWxsZGF0YSAlPiUKICBtdXRhdGUobWFpbmdyb3VwID0gY2FzZV93aGVuKAogICAgaGVhcmluZyA9PSAiRGVhZiIgJiBhb2FzbCA8IDQgfiAiRGVhZkVhcmx5IiwKICAgIGhlYXJpbmcgPT0gIkRlYWYiICYgYW9hc2wgPj0gNCB+ICJEZWFmTGF0ZSIsCiAgICBtYWluZ3JvdXAgPT0gIkhlYXJpbmdMYXRlQVNMIiB+ICJIZWFyaW5nTGF0ZSIsCiAgICBtYWluZ3JvdXAgPT0gIkhlYXJpbmdOb3ZpY2VBU0wiIH4gIkhlYXJpbmdOb3ZpY2UiCiAgKSkKCiMgQ3JlYXRlIFBhcnRpY2lwYW50IERlbW9ncmFwaGljcyBUYWJsZQpwYXJ0aWNpcGFudF9pbmZvIDwtIGZ1bGxkYXRhICU+JQogIHNlbGVjdCgtKGFjYzpnaXN0KSkgJT4lCiAgc2VsZWN0KC0odmlkZW86ZGlyZWN0aW9uKSkgJT4lCiAgZGlzdGluY3QoKSAlPiUgCiAgZ3JvdXBfYnkobWFpbmdyb3VwKSAlPiUKICBzdW1tYXJpc2UobiA9IG4oKSwKICAgICAgICAgICAgYWdlX21lYW4gPSBtZWFuKGFnZSksCiAgICAgICAgICAgIGFnZV9zZCA9IHNkKGFnZSksCiAgICAgICAgICAgIGFvYXNsX21lYW4gPSBtZWFuKGFvYXNsKSwKICAgICAgICAgICAgYW9hc2xfc2QgPSBzZChhb2FzbCksCiAgICAgICAgICAgIHNpZ255cnNfbWVhbiA9IG1lYW4oc2lnbnlycyksCiAgICAgICAgICAgIHNpZ255cnNfc2QgPSBzZChzaWdueXJzKSwKICAgICAgICAgICAgc2VsZnJhdGVfbWVhbiA9IG1lYW4oc2VsZnJhdGUpLAogICAgICAgICAgICBzZWxmcmF0ZV9zZCA9IHNkKHNlbGZyYXRlKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZV9pZihpcy5kb3VibGUsIGZ1bnMocm91bmQoLiwgMikpKSAlPiUKICBtdXRhdGUoYWdlID0gcGFzdGUoYWdlX21lYW4sICLCsSIsIGFnZV9zZCwgc2VwID0gIiAiKSwKICAgICAgICAgYW9hc2wgPSBwYXN0ZShhb2FzbF9tZWFuLCAiwrEiLCBhb2FzbF9zZCwgc2VwID0gIiAiKSwKICAgICAgICAgc2lnbnlycyA9IHBhc3RlKHNpZ255cnNfbWVhbiwgIsKxIiwgc2lnbnlyc19zZCwgc2VwID0gIiAiKSwKICAgICAgICAgc2VsZnJhdGUgPSBwYXN0ZShzZWxmcmF0ZV9tZWFuLCAiwrEiLCBzZWxmcmF0ZV9zZCwgc2VwID0gIiAiKSkgJT4lCiAgc2VsZWN0KC0oYWdlX21lYW46c2VsZnJhdGVfc2QpKQoKcGFydGljaXBhbnRfaW5mbwpgYGAKIyMgUGFydGljaXBhbnQgQU5PVkFzIAoKQmVsb3cgYXJlIHRoZSBBTk9WQSBvdXRwdXRzIGZvciBwYXJ0aWNpcGFudCBkZW1vZ3JhcGhpY3MsIGFuZCBMU0RzIGZvciBlYWNoLiAKClBhcnRpY2lwYW50cycgYWdlCmBgYHtyIHN1YmplY3QgYW5vdmEgYWdlLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIE1ha2UgdGhlIHBhcnRpY2lwYW50IGRhdGEgZnJhbWUKcF9hbm92YXMgPC0gZnVsbGRhdGEgJT4lCiAgc2VsZWN0KC0oYWNjOmdpc3QpKSAlPiUKICBzZWxlY3QoLSh2aWRlbzpkaXJlY3Rpb24pKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIHNlbGVjdChtYWluZ3JvdXA6YW9hc2wpCgojIEFnZSBBTk9WQQpwX2FnZSA8LSBhb3YoYWdlIH4gbWFpbmdyb3VwLCBkYXRhID0gcF9hbm92YXMpCnN1bW1hcnkocF9hZ2UpCnBfYWdlX2xzZCA8LSBMU0QudGVzdChwX2FnZSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpJGNvbXBhcmlzb24KcF9hZ2VfbHNkCmBgYAoKClBhcnRpY2lwYW50cycgQW9BU0wKYGBge3Igc3ViamVjdCBhbm92YSBhb2FzbCwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBBb0FTTCBBTk9WQQpwX2FvYXNsIDwtIGFvdihhb2FzbCB+IG1haW5ncm91cCwgZGF0YSA9IHBfYW5vdmFzKQpzdW1tYXJ5KHBfYW9hc2wpCnBfYW9hc2xfbHNkIDwtIExTRC50ZXN0KHBfYW9hc2wsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKSRjb21wYXJpc29uCnBfYW9hc2xfbHNkCmBgYAoKUGFydGljaXBhbnRzJyBTaWduIFlycwpgYGB7ciBzdWJqZWN0IGFub3ZhIHNpZ255cnMsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgU2lnbnlycyBBTk9WQQpwX3NpZ255cnMgPC0gYW92KHNpZ255cnMgfiBtYWluZ3JvdXAsIGRhdGEgPSBwX2Fub3ZhcykKc3VtbWFyeShwX3NpZ255cnMpCnBfc2lnbnlyc19sc2QgPC0gTFNELnRlc3QocF9zaWdueXJzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkkY29tcGFyaXNvbgpwX3NpZ255cnNfbHNkCmBgYAoKUGFydGljaXBhbnRzJyBTZWxmLVJhdGluZwpgYGB7ciBzdWJqZWN0IGFub3ZhIHNlbGZyYXRlLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIFNlbGZyYXRlIEFOT1ZBCnBfc2VsZnJhdGUgPC0gYW92KHNlbGZyYXRlIH4gbWFpbmdyb3VwLCBkYXRhID0gcF9hbm92YXMpCnN1bW1hcnkocF9zZWxmcmF0ZSkKcF9zZWxmcmF0ZV9sc2QgPC0gTFNELnRlc3QocF9zZWxmcmF0ZSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpJGNvbXBhcmlzb24KcF9zZWxmcmF0ZV9sc2QKYGBgCgojIEdpc3QgJiBMZXhpY2FsIFJlY2FsbCBEYXRhCgojIyBUYWJsZXMgJiBDaGFydHMKCkxldCdzIGdlbmVyYXRlIGEgdGFibGUgZm9yIGxleGljYWwgcmVjYWxsIGFuZCBnaXN0IGZvciBmb3J3YXJkIHZzLiByZXZlcnNlZCBzdG9yaWVzLiAKCmBgYHtyIGxleCAmIGdpc3QgdGFibGV9CmxleGdpc3RfaW5mbyA8LSBmdWxsZGF0YSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKGxleF9tZWFuID0gbWVhbihhY2MsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIGxleF9zZCA9IHNkKGFjYywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgZ2lzdF9tZWFuID0gbWVhbihnaXN0KSwKICAgICAgICAgICAgZ2lzdF9zZCA9IHNkKGdpc3QpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlX2lmKGlzLmRvdWJsZSwgZnVucyhyb3VuZCguLCAyKSkpICU+JSAKICBtdXRhdGUobGV4ID0gcGFzdGUobGV4X21lYW4sICLCsSIsIGxleF9zZCwgc2VwID0gIiAiKSwKICAgICAgICAgZ2lzdCA9IHBhc3RlKGdpc3RfbWVhbiwgIsKxIiwgZ2lzdF9zZCwgc2VwID0gIiAiKSkgJT4lCiAgc2VsZWN0KC0obGV4X21lYW46Z2lzdF9zZCkpICU+JQogIGdhdGhlcihtZXRyaWMsIHZhbHVlLCBsZXg6Z2lzdCkgJT4lCiAgdW5pdGUoIm1ldHJpYyIsIGMobWV0cmljLCBkaXJlY3Rpb24pLCBzZXAgPSAiXyIpICU+JQogIHNwcmVhZChtZXRyaWMsIHZhbHVlKSAlPiUKICBwcmludCgpCmBgYAoKQW5kIHRoZW4gYmFyIGNoYXJ0cyB0b28gYWZ0ZXIgdGhhdCB3aXRoIGVycm9yIGJhcnMuIAoKYGBge3IgbGV4IGFuZCBnaXN0IGJhciBjaGFydHN9CiMgR2lzdCBiYXIgY2hhcnQKZ2lzdF9iYXIgPC0gZnVsbGRhdGEgJT4lIHNlbGVjdChwYXJ0aWNpcGFudCwgbWFpbmdyb3VwLCBkaXJlY3Rpb24sIGdpc3QpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcGFydGljaXBhbnQsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKGdpc3QgPSBtZWFuKGdpc3QpKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKGdpc3QpLAogICAgICAgICAgICBzZCA9IHNkKGdpc3QpLAogICAgICAgICAgICBjb3VudCA9IG4oKSwKICAgICAgICAgICAgc2UgPSBzZC9zcXJ0KGNvdW50KSkKCmdncGxvdChnaXN0X2JhciwgYWVzKHggPSBtYWluZ3JvdXAsIHkgPSBtZWFuLCBmaWxsID0gZGlyZWN0aW9uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsgCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW4tc2UsIHltYXggPSBtZWFuK3NlKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLCB3aWR0aCA9IDAuNSkgKwogIGxhYnModGl0bGUgPSAiU3RvcnkgQ29tcHJlaGVuc2lvbiAoR2lzdCkiLCBzdWJ0aXRsZSA9ICJFcnJvciBiYXJzIHJlcHJlc2VudCBTRSIsIHggPSAiIiwgeSA9ICJtZWFuIGdpc3QiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnQsIGxpbWl0cyA9IGMoMCwxKSkKCiMgTGV4IGJhciBjaGFydApsZXhfYmFyIDwtIGZ1bGxkYXRhICU+JSBzZWxlY3QocGFydGljaXBhbnQsIG1haW5ncm91cCwgZGlyZWN0aW9uLCBhY2MpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcGFydGljaXBhbnQsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKGFjYyA9IG1lYW4oYWNjLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKGFjYywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgc2QgPSBzZChhY2MsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIGNvdW50ID0gbigpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQoY291bnQpKQoKZ2dwbG90KGxleF9iYXIsIGFlcyh4ID0gbWFpbmdyb3VwLCB5ID0gbWVhbiwgZmlsbCA9IGRpcmVjdGlvbikpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuLXNlLCB5bWF4ID0gbWVhbitzZSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwgd2lkdGggPSAwLjUpICsKICBsYWJzKHRpdGxlID0gIkxleGljYWwgUmVjYWxsIiwgc3VidGl0bGUgPSAiRXJyb3IgYmFycyByZXByZXNlbnQgU0UiLCB4ID0gIiIsIHkgPSAibWVhbiBhY2N1cmFjeSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCwgbGltaXRzID0gYygwLDEpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLjUsIGxpbmV0eXBlID0gImRvdHRlZCIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLjUsMSkpCmBgYAoKIyMgQU5PVkEgUGxhbgpOZXh0LCB3ZSdyZSBnb2luZyB0byBkbyBBTk9WQXMgYW5kIEFOQ09WQXMuIFdlJ2xsIGFsd2F5cyBkbyBpdCBpbiB0aGlzIG9yZGVyLiBUaGUgZmlyc3QgdGhyZWUgQU5PVkFzIHdpbGwgYmUgZm9sbG93ZWQgYnkgTFNEIG9mIHRoZSBmb3VyIG1haW5ncm91cHMgd2l0aCAqdW5jb3JyZWN0ZWQgcC12YWx1ZXMuKiAKCjEuIEFOT1ZBIHdpdGggZmFjdG9ycyBNYWluR3JvdXAgJiBEaXJlY3Rpb24KMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5CjMuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIFJldmVyc2Ugb25seSAKNC4gQU5DT1ZBIHdpdGggZmFjdG9yIERpcmVjdGlvbiwgYW5kIGNvdmFyaWF0ZSBBb0FTTCBhbmQgQWdlCjUuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQW9BU0wgYW5kIEFnZSwgZm9yIEZvcndhcmQgb25seQo2LiBSZWdyZXNzaW9uIHdpdGggdmFyaWFibGVzIEFvQVNMIGFuZCBBZ2UsIGZvciBSZXZlcnNlIG9ubHkuIAoKSSBkaWQgbm90IGluY2x1ZGUgQWdlIGFzIGEgY292YXJpYXRlIGluIHRoZSBmaXJzdCAzIEFOT1ZBcyBiZWNhdXNlIHRoZXkgZGlkIG5vdCBhZGQgdG8gb3IgY2hhbmdlIHRoZSBtb2RlbCBpbiBhbnkgc2lnbmlmaWNhbnQgd2F5LiAKCiMjIEdpc3QgQU5PVkFzCgoxLiBBTk9WQSB3aXRoIGZhY3RvcnMgTWFpbkdyb3VwICYgRGlyZWN0aW9uLgoKYGBge3IgZ2lzdCBhbm92YTEsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBGaXJzdCBsZXQncyBtYWtlIHRoZSBwYXJ0aWNpcGFudC1sZXZlbCBkYXRhc2V0IHdpdGggd2hpY2ggd2UnbGwgZG8gb3VyIEFOQ09WQXMuIApwYXJ0aWNpcGFudF9kYXRhIDwtIGZ1bGxkYXRhICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcGFydGljaXBhbnQsIGRpcmVjdGlvbikgJT4lCiAgbXV0YXRlKGdpc3QgPSBtZWFuKGdpc3QsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIGFjYyA9IG1lYW4oYWNjLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBzZWxlY3QoaWQsIHBhcnRpY2lwYW50LCBoZWFyaW5nLCBtYWluZ3JvdXAsIGRpcmVjdGlvbiwgYWdlLCBhb2FzbCwgYWNjLCBnaXN0KSAlPiUKICBkaXN0aW5jdCgpCgojIEdpc3QgQU5PVkEgMQpnaXN0X2FvdjEgPC0gYW92KGdpc3QgfiBtYWluZ3JvdXAgKiBkaXJlY3Rpb24sIGRhdGEgPSBwYXJ0aWNpcGFudF9kYXRhKQpzdW1tYXJ5KGdpc3RfYW92MSkKZ2lzdF9sc2QxIDwtIExTRC50ZXN0KGdpc3RfYW92MSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCmdpc3RfbHNkMSRjb21wYXJpc29uCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LiBBbHNvIGEgS3J1c2thbC1XYWxsaXMgdGVzdC4gQW5kIENoaS1TcSB0b28uIAoKYGBge3IgZ2lzdCBhbm92YTIsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBHaXN0IEFOT1ZBIDIKZ2lzdF9hb3YyIDwtIGFvdihnaXN0IH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKHBhcnRpY2lwYW50X2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQpzdW1tYXJ5KGdpc3RfYW92MikKZ2lzdF9sc2QyIDwtIExTRC50ZXN0KGdpc3RfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCmdpc3RfbHNkMiRjb21wYXJpc29uCgojIEtXIE5vbi1wYXJhbWV0cmljIHRlc3QgKGxpa2Ugb25lLXdheSBBTk9WQSkKa3J1c2thbC50ZXN0KGdpc3QgfiBtYWluZ3JvdXAsIGRhdGEgPSBhcy5tYXRyaXgoZmlsdGVyKHBhcnRpY2lwYW50X2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKSkKCiMgQ2hpIFNxCmdpc3RfY2hpc3FfZncgPC0gcGFydGljaXBhbnRfZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZmlsdGVyKGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpICU+JQogIHNlbGVjdChtYWluZ3JvdXAsIGdpc3QpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgZ2lzdCkgJT4lCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUKICBzcHJlYWQoZ2lzdCwgY291bnQpICU+JQogIHJlbmFtZShub25lID0gIjAiLAogICAgICAgICBvbmUgPSAiMC41IiwKICAgICAgICAgYm90aCA9ICIxIikKCmdpc3RfY2hpc3FfZndbaXMubmEoZ2lzdF9jaGlzcV9mdyldIDwtIDBMCmdpc3RfY2hpc3FfZncgPC0gY2JpbmQoZ2lzdF9jaGlzcV9md1ssIm5vbmUiXSwgZ2lzdF9jaGlzcV9md1ssIm9uZSJdLCBnaXN0X2NoaXNxX2Z3WywiYm90aCJdKQpjaGlzcS50ZXN0KGdpc3RfY2hpc3FfZncpCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIGdpc3QgYW5vdmEzLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgR2lzdCBBTk9WQSAzCmdpc3RfYW92MyA8LSBhb3YoZ2lzdCB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkoZ2lzdF9hb3YzKQpnaXN0X2xzZDMgPC0gTFNELnRlc3QoZ2lzdF9hb3YzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKZ2lzdF9sc2QzJGNvbXBhcmlzb24KCiMgS1cgTm9uLXBhcmFtZXRyaWMgdGVzdCAobGlrZSBvbmUtd2F5IEFOT1ZBKQprcnVza2FsLnRlc3QoZ2lzdCB+IG1haW5ncm91cCwgZGF0YSA9IGFzLm1hdHJpeChmaWx0ZXIocGFydGljaXBhbnRfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKSkKCiMgQ2hpIFNxCmdpc3RfY2hpc3FfcnYgPC0gcGFydGljaXBhbnRfZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZmlsdGVyKGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSAlPiUKICBzZWxlY3QobWFpbmdyb3VwLCBnaXN0KSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGdpc3QpICU+JQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgc3ByZWFkKGdpc3QsIGNvdW50KSAlPiUKICByZW5hbWUobm9uZSA9ICIwIiwKICAgICAgICAgb25lID0gIjAuNSIsCiAgICAgICAgIGJvdGggPSAiMSIpCgpnaXN0X2NoaXNxX3J2W2lzLm5hKGdpc3RfY2hpc3FfcnYpXSA8LSAwTApnaXN0X2NoaXNxX3J2IDwtIGNiaW5kKGdpc3RfY2hpc3FfcnZbLCJub25lIl0sIGdpc3RfY2hpc3FfcnZbLCJvbmUiXSwgZ2lzdF9jaGlzcV9ydlssImJvdGgiXSkKY2hpc3EudGVzdChnaXN0X2NoaXNxX3J2KQpgYGAKCjQuIEFOQ09WQSB3aXRoIGZhY3RvciBEaXJlY3Rpb24sIGFuZCB2YXJpYWJsZXMgQW9BU0wgYW5kIEFnZS4KCmBgYHtyIGdpc3QgYW5vdmE0LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgR2lzdCBBTk9WQSA0Cmdpc3RfYW92NCA8LSBhb3YoZ2lzdCB+IGRpcmVjdGlvbiAqIGFvYXNsICogYWdlLCBkYXRhID0gcGFydGljaXBhbnRfZGF0YSkKc3VtbWFyeShnaXN0X2FvdjQpCmBgYAoKNS4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBZ2UgYW5kIEFvQVNMLCBmb3IgRm9yd2FyZCBvbmx5CgpgYGB7ciBnaXN0IGFub3ZhNSwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIEdpc3QgQU5PVkEgNQpnaXN0X2FvdjUgPC0gbG0oZ2lzdCB+IGFvYXNsICogYWdlLCBkYXRhID0gZmlsdGVyKHBhcnRpY2lwYW50X2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQpzdW1tYXJ5KGdpc3RfYW92NSkKYGBgCgo2LiBSZWdyZXNzaW9uIHdpdGggdmFyaWFibGVzIEFvQVNMIGFuZCBBZ2UsIGZvciBSZXZlcnNlIG9ubHkuIAoKYGBge3IgZ2lzdCBhbm92YTYsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBHaXN0IEFOT1ZBIDYKZ2lzdF9hb3Y2IDwtIGxtKGdpc3QgfiBhb2FzbCAqIGFnZSwgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkoZ2lzdF9hb3Y2KQpgYGAKCiMjIExleGljYWwgUmVjYWxsIEFOT1ZBcwoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIGFjYyBhbm92YTEsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBMZXhpY2FsIFJlY2FsbCBBTk9WQSAxCmFjY19hb3YxIDwtIGFvdihhY2MgfiBtYWluZ3JvdXAgKiBkaXJlY3Rpb24sIGRhdGEgPSBwYXJ0aWNpcGFudF9kYXRhKQpzdW1tYXJ5KGFjY19hb3YxKQphY2NfbHNkMSA8LSBMU0QudGVzdChhY2NfYW92MSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCmFjY19sc2QxJGNvbXBhcmlzb24KYGBgCgoyLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBGb3J3YXJkIG9ubHkuCgpgYGB7ciBhY2MgYW5vdmEyLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgTGV4aWNhbCBSZWNhbGwgQU5PVkEgMgphY2NfYW92MiA8LSBhb3YoYWNjIH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKHBhcnRpY2lwYW50X2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQpzdW1tYXJ5KGFjY19hb3YyKQphY2NfbHNkMiA8LSBMU0QudGVzdChhY2NfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCmFjY19sc2QyJGNvbXBhcmlzb24KYGBgCgozLiBBTk9WQSB3aXRoIGZhY3RvciBNYWluR3JvdXAsIGZvciBSZXZlcnNlIG9ubHkuIAoKYGBge3IgYWNjIGFub3ZhMywgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIExleGljYWwgUmVjYWxsIEFOT1ZBIDMKYWNjX2FvdjMgPC0gYW92KGFjYyB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkoYWNjX2FvdjMpCmFjY19sc2QzIDwtIExTRC50ZXN0KGFjY19hb3YzLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKYWNjX2xzZDMkY29tcGFyaXNvbgpgYGAKCjQuIEFOQ09WQSB3aXRoIGZhY3RvciBEaXJlY3Rpb24sIGFuZCBjb3ZhcmlhdGUgQW9BU0wgYW5kIEFnZS4KCmBgYHtyIGFjYyBhbm92YTQsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBMZXhpY2FsIFJlY2FsbCBBTk9WQSA0CmFjY19hb3Y0IDwtIGFvdihhY2MgfiBkaXJlY3Rpb24gKiBhb2FzbCAqIGFnZSwgZGF0YSA9IHBhcnRpY2lwYW50X2RhdGEpCnN1bW1hcnkoYWNjX2FvdjQpCmBgYAoKNS4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBZ2UgYW5kIEFvQVNMLCBmb3IgRm9yd2FyZCBvbmx5CgpgYGB7ciBhY2MgYW5vdmE1LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgTGV4aWNhbCBSZWNhbGwgQU5PVkEgNQphY2NfYW92NSA8LSBsbShhY2MgfiBhb2FzbCAqIGFnZSwgZGF0YSA9IGZpbHRlcihwYXJ0aWNpcGFudF9kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShhY2NfYW92NSkKYGBgCgo2LiBSZWdyZXNzaW9uIHdpdGggdmFyaWFibGVzIEFvQVNMIGFuZCBBZ2UsIGZvciBSZXZlcnNlIG9ubHkuIAoKYGBge3IgYWNjIGFub3ZhNiwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIExleGljYWwgUmVjYWxsIEFOT1ZBIDYKYWNjX2FvdjYgPC0gbG0oYWNjIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIocGFydGljaXBhbnRfZGF0YSwgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIpKQpzdW1tYXJ5KGFjY19hb3Y2KQpgYGAKCgojIEFvQSBDb3JyZWxhdGlvbnMKCk5leHQsIHdlIHdhbnQgdG8gbG9vayBhdCBjb3JyZWxhdGlvbnMgYmV0d2VlbiBBb0EgYW5kIEdpc3QsIGFuZCBiZXR3ZW4gQW9BIGFuZCBMZXhpY2FsIFJlY2FsbC4gUmFpbiBhc2tlZCBmb3IgZm9yd2FyZCBhbmQgcmV2ZXJzZWQgc2VwYXJhdGVseSAoMSkgZGVhZiBvbmx5LCAoMikgaGVhcmluZyBvbmx5LCBhbmQgKDMpIGJvdGguIExldCdzIG1ha2UgaXQgd29yay4gCgpgYGB7ciByZXBhY2thZ2UgZGF0YSBmb3IgY29ycmVsYXRpb25zLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIExldCdzIG1ha2UgcGFydGljaXBhbnQtbGV2ZWwgZGF0YSwgYW5kIGhhdmUgZm9yd2FyZC9yZXZlcnNlZCBpbiBzZXBhcmF0ZSBjb2x1bW5zCmxleGdpc3RfZGF0YSA8LSBmdWxsZGF0YSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIHBhcnRpY2lwYW50LCBkaXJlY3Rpb24pICU+JQogIG11dGF0ZShnaXN0ID0gbWVhbihnaXN0LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICBsZXggPSBtZWFuKGFjYywgbmEucm0gPSBUUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIHNlbGVjdChtYWluZ3JvdXAsIHBhcnRpY2lwYW50LCBoZWFyaW5nLCBkaXJlY3Rpb24sIGFvYXNsLCBzaWdueXJzLCBhZ2UsIGdpc3QsIGxleCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBnYXRoZXIobWV0cmljLCB2YWx1ZSwgZ2lzdDpsZXgpICU+JQogIHVuaXRlKG1ldHJpY3ZhbHVlLCBjKG1ldHJpYywgZGlyZWN0aW9uKSwgc2VwID0gIl8iKSAlPiUKICBzcHJlYWQobWV0cmljdmFsdWUsIHZhbHVlKSAlPiUKICBzZWxlY3QoLXBhcnRpY2lwYW50LCAtbWFpbmdyb3VwKQoKbGV4Z2lzdF9kZWFmIDwtIGxleGdpc3RfZGF0YSAlPiUgZmlsdGVyKGhlYXJpbmcgPT0gIkRlYWYiKSAlPiUgc2VsZWN0KC1oZWFyaW5nKQpsZXhnaXN0X2hlYXJpbmcgPC0gbGV4Z2lzdF9kYXRhICU+JSBmaWx0ZXIoaGVhcmluZyA9PSAiSGVhcmluZyIpICU+JSBzZWxlY3QoLWhlYXJpbmcpCmxleGdpc3RfYWxsIDwtIGxleGdpc3RfZGF0YSAlPiUgc2VsZWN0KC1oZWFyaW5nKQoKIyBMb2FkIGF3ZXNvbWUgZnVuY3Rpb24gdG8gbWFrZSBjb3JyZWxhdGlvbiB0YWJsZXMgd2l0aCBzdGFycyBmb3Igc2lnbmlmaWNhbmNlCiMgRnJvbTogaHR0cHM6Ly9teW93ZWx0LmJsb2dzcG90LmNvLnVrLzIwMDgvMDQvYmVhdXRpZnVsLWNvcnJlbGF0aW9uLXRhYmxlcy1pbi1yLmh0bWwKY29yc3RhcnNsIDwtIGZ1bmN0aW9uKHgpeyAKcmVxdWlyZShIbWlzYykgCnggPC0gYXMubWF0cml4KHgpIApSIDwtIEhtaXNjOjpyY29ycih4KSRyIApwIDwtIEhtaXNjOjpyY29ycih4KSRQIAojIyBkZWZpbmUgbm90aW9ucyBmb3Igc2lnbmlmaWNhbmNlIGxldmVsczsgc3BhY2luZyBpcyBpbXBvcnRhbnQuCm15c3RhcnMgPC0gaWZlbHNlKHAgPCAuMDAxLCAiKioqIiwgaWZlbHNlKHAgPCAuMDEsICIqKiAiLCBpZmVsc2UocCA8IC4wNSwgIiogIiwgIiAiKSkpCiMjIHRydW5jdHVhdGUgdGhlIG1hdHJpeCB0aGF0IGhvbGRzIHRoZSBjb3JyZWxhdGlvbnMgdG8gdHdvIGRlY2ltYWwKUiA8LSBmb3JtYXQocm91bmQoY2JpbmQocmVwKC0xLjExLCBuY29sKHgpKSwgUiksIDIpKVssLTFdIAojIyBidWlsZCBhIG5ldyBtYXRyaXggdGhhdCBpbmNsdWRlcyB0aGUgY29ycmVsYXRpb25zIHdpdGggdGhlaXIgYXByb3ByaWF0ZSBzdGFycyAKUm5ldyA8LSBtYXRyaXgocGFzdGUoUiwgbXlzdGFycywgc2VwPSIiKSwgbmNvbD1uY29sKHgpKSAKZGlhZyhSbmV3KSA8LSBwYXN0ZShkaWFnKFIpLCAiICIsIHNlcD0iIikgCnJvd25hbWVzKFJuZXcpIDwtIGNvbG5hbWVzKHgpIApjb2xuYW1lcyhSbmV3KSA8LSBwYXN0ZShjb2xuYW1lcyh4KSwgIiIsIHNlcD0iIikgCiMjIHJlbW92ZSB1cHBlciB0cmlhbmdsZQpSbmV3IDwtIGFzLm1hdHJpeChSbmV3KQpSbmV3W3VwcGVyLnRyaShSbmV3LCBkaWFnID0gVFJVRSldIDwtICIiClJuZXcgPC0gYXMuZGF0YS5mcmFtZShSbmV3KSAKIyMgcmVtb3ZlIGxhc3QgY29sdW1uIGFuZCByZXR1cm4gdGhlIG1hdHJpeCAod2hpY2ggaXMgbm93IGEgZGF0YSBmcmFtZSkKUm5ldyA8LSBjYmluZChSbmV3WzE6bGVuZ3RoKFJuZXcpLTFdKQpyZXR1cm4oUm5ldykgCn0KCiMgQ29ycmVsYXRpb25zIGZvciBEZWFmCnByaW50KCJERUFGIENvcnJlbGF0aW9ucyAtIFBlYXJzb24ncyByIikKI2NvcnN0YXJzbChsZXhnaXN0X2RlYWYpCkhtaXNjOjpyY29ycihhcy5tYXRyaXgobGV4Z2lzdF9kZWFmKSkkcgpwcmludCgiREVBRiBDb3JyZWxhdGlvbnMgLSBQLXZhbHVlcyIpCkhtaXNjOjpyY29ycihhcy5tYXRyaXgobGV4Z2lzdF9kZWFmKSkkUApjYXQocGFzdGUoIiIsIlxuIiwiIikpCgojIENvcnJlbGF0aW9ucyBmb3IgSGVhcmluZwpwcmludCgiSEVBUklORyBDb3JyZWxhdGlvbnMgLSBQZWFyc29uJ3MgciIpCiNjb3JzdGFyc2wobGV4Z2lzdF9oZWFyaW5nKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGxleGdpc3RfaGVhcmluZykpJHIKcHJpbnQoIkhFQVJJTkcgQ29ycmVsYXRpb25zIC0gUC12YWx1ZXMiKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGxleGdpc3RfaGVhcmluZykpJFAKY2F0KHBhc3RlKCIiLCJcbiIsIiIpKQoKIyBDb3JyZWxhdGlvbnMgZm9yIEFsbApwcmludCgiQUxMIENvcnJlbGF0aW9ucyAtIFBlYXJzb24ncyByIikKI2NvcnN0YXJzbChsZXhnaXN0X2FsbCkKSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChsZXhnaXN0X2FsbCkpJHIKcHJpbnQoIkFMTCBDb3JyZWxhdGlvbnMgLSBQLXZhbHVlcyIpCkhtaXNjOjpyY29ycihhcy5tYXRyaXgobGV4Z2lzdF9hbGwpKSRQCgpgYGAKCkknbSBhbHNvIGluY2x1ZGluZyBuaWNlbHkgZm9ybWF0dGVkIHRhYmxlcyB3aXRoICoqKiBpbmRpY2F0b3JzIG9mIHNpZ25pZmljYW5jZSBmb3IgcXVpY2sgcmVmZXJlbmNpbmcuIE9yZGVyOiBEZWFmLCBIZWFyaW5nLCBBbGwuIAoKYGBge3IgcHJldHR5IGNvcnJlbGF0aW9uc30KY29yc3RhcnNsKGxleGdpc3RfZGVhZikKY29yc3RhcnNsKGxleGdpc3RfaGVhcmluZykKY29yc3RhcnNsKGxleGdpc3RfYWxsKQpgYGAKCiMjIFNjYXR0ZXJwbG90IG9mIENvcnJlbGF0aW9ucwpMZXQncyB2aXN1YWxpemUgd2hhdCdzIGhhcHBlbmluZyB3aXRoIHRoZSBjb3JyZWxhdGlvbnMgaGVyZS4gCmBgYHtyIGNvcnJlbGF0aW9uIGNoYXJ0cywgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3BhaXJzKGxleGdpc3RfZGF0YSwgY29sdW1ucyA9IGMoMjo4KSwgYWVzKGNvbG9yID0gaGVhcmluZykpCmBgYAoKCiMgRXllIEdhemUgRGF0YQoKTm93IGV5ZSBnYXplIGRhdGEuIEJveHBsb3RzIGZpcnN0LiBBbHNvIGhlcmUsIHdlJ3JlIHJlbmFtaW5nICJjaGluIiB0byAibmVjayIgYmVjYXVzZSB0aGF0J3Mgd2hhdCBpdCBhY3R1YWxseSBpcyEgQnV0IHdlIGFsc28gaGF2ZSB0byBmaXggYWxsIE5BJ3MgaW4gdGhlIHBlcmNlbnRhZ2VzIHRvIHplcm9zLCBiZWN1YXNlIHRoYXQncyB3aGF0IHRoZXkgYWN0dWFsbHkgYXJlLiAKYGBge3IgZXllIGdhemUgYm94cGxvdH0KIyByZW5hbWUgY2hpbiB0byBuZWNrCmZ1bGxkYXRhIDwtIGZ1bGxkYXRhICU+JQogIHJlbmFtZShuZWNrID0gY2hpbikgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6dXBwZXJjaGVzdCkKCiMgRml4IGFsbCBOQSdzIGluIFBlcmNlbnQgY29sdW1uIHRvIDAKZml4cGVyY2VudCA8LSBmdWxsZGF0YSRwZXJjZW50CmZ1bGxkYXRhJHBlcmNlbnQgPC0gY29hbGVzY2UoZml4cGVyY2VudCwgMCkKZnVsbGRhdGEgPC0gZnVsbGRhdGEgJT4lCiAgc3ByZWFkKGFvaSwgcGVyY2VudCkKCmZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgc2VsZWN0KGRpcmVjdGlvbiwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gYW9pLCB5ID0gcGVyY2VudCwgZmlsbCA9IGRpcmVjdGlvbikpICsgZ2VvbV9ib3hwbG90KCkKYGBgCgpCdXQgbGV0J3MgdHJ5IGVycm9yIGNoYXJ0cyB0b28hIEluc3RlYWQgb2YgYm94cGxvdHMuCgpgYGB7ciBleWUgZ2F6ZSBlcnJvciBiYXIgY2hhcnR9CmZ1bGxkYXRhX2Vycm9yIDwtIGZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6dXBwZXJjaGVzdCkgJT4lCiAgZ3JvdXBfYnkoaWQsIGRpcmVjdGlvbiwgYW9pKSAlPiUKICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgZ3JvdXBfYnkoZGlyZWN0aW9uLCBhb2kpICU+JQogIHN1bW1hcmlzZShtZWFuID0gbWVhbihwZXJjZW50LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBzZCA9IHNkKHBlcmNlbnQsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIGNvdW50ID0gbigpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQoY291bnQpKQpmdWxsZGF0YV9lcnJvciRhb2kgPC0gZmN0X3JlbGV2ZWwoZnVsbGRhdGFfZXJyb3IkYW9pLCBjKCJmb3JlaGVhZCIsImV5ZXMiLCJtb3V0aCIsIm5lY2siLCJ1cHBlcmNoZXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWlkY2hlc3QiLCJsb3dlcmNoZXN0IiwiYmVsbHkiLCJsZWZ0IiwicmlnaHQiKSkKCmZ1bGxkYXRhX2Vycm9yICU+JQogIGdncGxvdChhZXMoeCA9IGFvaSwgeSA9IG1lYW4sIGZpbGwgPSBkaXJlY3Rpb24pKSArIAogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbi1zZSwgeW1heCA9IG1lYW4rc2UpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHdpZHRoID0gMC41KSArCiAgbGFicyh0aXRsZSA9ICJFeWUgR2F6ZSBCZWhhdmlvciIsIHN1YnRpdGxlID0gIkVycm9yIGJhcnMgcmVwcmVzZW50IFNFIiwgeCA9ICIiLCB5ID0gInBlcmNlbnQgbG9va2luZyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudCwgbGltaXRzID0gYygwLC43NSkpCmBgYAoKIyMgQmlnIFRocmVlLVdheSBBTk9WQQpOb3cgd2UncmUgZ29pbmcgdG8gdHJ5IGEgdGhyZWUtd2F5IEdyb3VwIHggRGlyZWN0aW9uIHggQU9JIEFOT1ZBIHdpdGggdGhlIHRvcCAzIEFPSXMgKEV5ZXMsIE1vdXRoLCBOZWNrKQoKYGBge3IgYmlnIGFub3ZhIGFvaTMsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KYW9pMyA8LSBjKCdleWVzJywnbW91dGgnLCduZWNrJykKCiMgT3JnYW5pemUgdGhlIGRhdGEgYnkgdGhvc2UgQU9JcyAoYnV0IGFnYWluIHdlIG5lZWQgcGFydGljaXBhbnQtbGV2ZWwgZmlyc3QpCmFvaTNfZGF0YSA8LSBmdWxsZGF0YSAlPiUKICBmaWx0ZXIoZXllX2V4Y2x1ZGUgPT0gRkFMU0UpICU+JQogIHNlbGVjdChpZCwgbWFpbmdyb3VwLCBoZWFyaW5nLCBhb2FzbCwgYWdlLCBkaXJlY3Rpb24sIGJlbGx5OnVwcGVyY2hlc3QpICU+JQogIGdhdGhlcihhb2ksIHBlcmNlbnQsIGJlbGx5OnVwcGVyY2hlc3QpICU+JQogIGdyb3VwX2J5KGlkLCBkaXJlY3Rpb24sIGFvaSkgJT4lCiAgbXV0YXRlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtID0gVFJVRSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIGZpbHRlcihhb2kgJWluJSBhb2kzKSAlPiUKICBzcHJlYWQoYW9pLCBwZXJjZW50KQoKIyBMaW1pdCB0byBleWVzIG1vdXRoIG5lY2sKYmlnX2Fvdl9hb2kzIDwtIGFvaTNfZGF0YSAlPiUKICBnYXRoZXIoYW9pLCBwZXJjZW50LCBleWVzOm5lY2spICU+JQogIGFvdihwZXJjZW50IH4gbWFpbmdyb3VwICogZGlyZWN0aW9uICogYW9pLCBkYXRhID0gLikKCnN1bW1hcnkoYmlnX2Fvdl9hb2kzKQoKYmlnX2Fvdl9hb2kzX2xzZCA8LSBMU0QudGVzdChiaWdfYW92X2FvaTMsICJhb2kiLCBncm91cCA9IEZBTFNFKQpiaWdfYW92X2FvaTNfbHNkJGNvbXBhcmlzb24KYGBgCgojIyBBbGwgdGhlIEFPSSByYXcgbnVtYmVycy9hdmVyYWdlcwpMZXQncyBnZXQgYSB0YWJsZSBvZiBvdXIgcmF3IG51bWJlcnMgaGVyZSwgYnkgZ3JvdXAKCmBgYHtyIGFvaSByYXcsIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQphb2kzX2RhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShleWVzID0gbWVhbihleWVzLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBtb3V0aCA9IG1lYW4obW91dGgsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG5lY2sgPSBtZWFuKG5lY2ssIG5hLnJtID0gVFJVRSkpCgphb2kzX2RhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShleWVzID0gbWVhbihleWVzLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBtb3V0aCA9IG1lYW4obW91dGgsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG5lY2sgPSBtZWFuKG5lY2ssIG5hLnJtID0gVFJVRSkpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCkgJT4lCiAgc3VtbWFyaXNlKGV5ZXMgPSBtZWFuKGV5ZXMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG1vdXRoID0gbWVhbihtb3V0aCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbmVjayA9IG1lYW4obmVjaywgbmEucm0gPSBUUlVFKSkgIAoKYW9pM19kYXRhICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UoZXllcyA9IG1lYW4oZXllcywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbW91dGggPSBtZWFuKG1vdXRoLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBuZWNrID0gbWVhbihuZWNrLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBncm91cF9ieShkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShleWVzID0gbWVhbihleWVzLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBtb3V0aCA9IG1lYW4obW91dGgsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG5lY2sgPSBtZWFuKG5lY2ssIG5hLnJtID0gVFJVRSkpICAKCmFvaTNfZGF0YSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKGV5ZXMgPSBtZWFuKGV5ZXMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIG1vdXRoID0gbWVhbihtb3V0aCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbmVjayA9IG1lYW4obmVjaywgbmEucm0gPSBUUlVFKSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwKSAlPiUKICBzdW1tYXJpc2UoZXllcyA9IG1lYW4oZXllcywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbW91dGggPSBtZWFuKG1vdXRoLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBuZWNrID0gbWVhbihuZWNrLCBuYS5ybSA9IFRSVUUpKSAlPiUKICB1bmdyb3VwKCkgJT4lIAogIGdhdGhlcihhb2ksIHBlcmNlbnQsIGV5ZXM6bmVjaykgJT4lCiAgZ3JvdXBfYnkoYW9pKSAlPiUKICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCwgbmEucm0gPSBUUlVFKSkKYGBgCgoKIyMgRXllcwoKMS4gQU5PVkEgd2l0aCBmYWN0b3JzIE1haW5Hcm91cCAmIERpcmVjdGlvbi4KCmBgYHtyIGV5ZXMgYW5vdmExLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CgojIGV5ZXMgQU5DT1ZBIDEKZXllc19hb3YxIDwtIGFvdihleWVzIH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gYW9pM19kYXRhKQpzdW1tYXJ5KGV5ZXNfYW92MSkKIyBleWVzX2xzZDEgPC0gTFNELnRlc3QoZXllc19hb3YxLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBleWVzX2xzZDEkY29tcGFyaXNvbgpgYGAKCjIuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIEZvcndhcmQgb25seS4KCmBgYHtyIGV5ZXMgYW5vdmEyLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgZXllcyBBTk9WQSAyCmV5ZXNfYW92MiA8LSBhb3YoZXllcyB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihhb2kzX2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQpzdW1tYXJ5KGV5ZXNfYW92MikKIyBleWVzX2xzZDIgPC0gTFNELnRlc3QoZXllc19hb3YyLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBleWVzX2xzZDIkY29tcGFyaXNvbgpgYGAKCjMuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIFJldmVyc2Ugb25seS4gCgpgYGB7ciBleWVzIGFub3ZhMywgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIGV5ZXMgQU5PVkEgMwpleWVzX2FvdjMgPC0gYW92KGV5ZXMgfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkoZXllc19hb3YzKQojIGV5ZXNfbHNkMyA8LSBMU0QudGVzdChleWVzX2FvdjMsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIGV5ZXNfbHNkMyRjb21wYXJpc29uCmBgYAoKNC4gQU5DT1ZBIHdpdGggZmFjdG9yIERpcmVjdGlvbiwgYW5kIGNvdmFyaWF0ZSBBb0FTTCBhbmQgQWdlLgoKYGBge3IgZXllcyBhbm92YTQsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBleWVzIEFOT1ZBIDQKZXllc19hb3Y0IDwtIGFvdihleWVzIH4gZGlyZWN0aW9uICogYW9hc2wgKiBhZ2UsIGRhdGEgPSBhb2kzX2RhdGEpCnN1bW1hcnkoZXllc19hb3Y0KQpgYGAKCjUuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIEZvcndhcmQgb25seQoKYGBge3IgZXllcyBhbm92YTUsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBleWVzIEFOT1ZBIDUKZXllc19hb3Y1IDwtIGxtKGV5ZXMgfiBhb2FzbCAqIGFnZSwgZGF0YSA9IGZpbHRlcihhb2kzX2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQpzdW1tYXJ5KGV5ZXNfYW92NSkKYGBgCgo2LiBSZWdyZXNzaW9uIHdpdGggdmFyaWFibGVzIEFnZSBhbmQgQW9BU0wsIGZvciBSZXZlcnNlIG9ubHkKCmBgYHtyIGV5ZXMgYW5vdmE2LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgZXllcyBBTk9WQSA2CmV5ZXNfYW92NiA8LSBsbShleWVzIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkoZXllc19hb3Y2KQpgYGAKCiMjIE1vdXRoCgoxLiBBTk9WQSB3aXRoIGZhY3RvcnMgTWFpbkdyb3VwICYgRGlyZWN0aW9uLgoKYGBge3IgbW91dGggYW5vdmExLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CgojIG1vdXRoIEFOQ09WQSAxCm1vdXRoX2FvdjEgPC0gYW92KG1vdXRoIH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gYW9pM19kYXRhKQpzdW1tYXJ5KG1vdXRoX2FvdjEpCm1vdXRoX2xzZDEgPC0gTFNELnRlc3QobW91dGhfYW92MSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCm1vdXRoX2xzZDEkY29tcGFyaXNvbgpgYGAKCjIuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIEZvcndhcmQgb25seS4KCmBgYHtyIG1vdXRoIGFub3ZhMiwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG1vdXRoIEFOT1ZBIDIKbW91dGhfYW92MiA8LSBhb3YobW91dGggfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShtb3V0aF9hb3YyKQojIG1vdXRoX2xzZDIgPC0gTFNELnRlc3QobW91dGhfYW92MiwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgbW91dGhfbHNkMiRjb21wYXJpc29uCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIG1vdXRoIGFub3ZhMywgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG1vdXRoIEFOT1ZBIDMKbW91dGhfYW92MyA8LSBhb3YobW91dGggfiBtYWluZ3JvdXAsIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkobW91dGhfYW92MykKIyBtb3V0aF9sc2QzIDwtIExTRC50ZXN0KG1vdXRoX2FvdjMsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIG1vdXRoX2xzZDMkY29tcGFyaXNvbgpgYGAKCjQuIEFOQ09WQSB3aXRoIGZhY3RvciBEaXJlY3Rpb24sIGFuZCBjb3ZhcmlhdGUgQW9BU0wgYW5kIEFnZS4KCmBgYHtyIG1vdXRoIGFub3ZhNCwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG1vdXRoIEFOT1ZBIDQKbW91dGhfYW92NCA8LSBhb3YobW91dGggfiBkaXJlY3Rpb24gKiBhb2FzbCAqIGFnZSwgZGF0YSA9IGFvaTNfZGF0YSkKc3VtbWFyeShtb3V0aF9hb3Y0KQpgYGAKCjUuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIEZvcndhcmQgb25seQoKYGBge3IgbW91dGggYW5vdmE1LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgbW91dGggQU5PVkEgNQptb3V0aF9hb3Y1IDwtIGxtKG1vdXRoIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gImZvcndhcmQiKSkKc3VtbWFyeShtb3V0aF9hb3Y1KQpgYGAKCjYuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIFJldmVyc2Ugb25seQoKYGBge3IgbW91dGggYW5vdmE2LCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgbW91dGggQU5PVkEgNgptb3V0aF9hb3Y2IDwtIGxtKG1vdXRoIH4gYW9hc2wgKiBhZ2UsIGRhdGEgPSBmaWx0ZXIoYW9pM19kYXRhLCBkaXJlY3Rpb24gPT0gInJldmVyc2VkIikpCnN1bW1hcnkobW91dGhfYW92NikKYGBgCgojIyBOZWNrCgoxLiBBTk9WQSB3aXRoIGZhY3RvcnMgTWFpbkdyb3VwICYgRGlyZWN0aW9uLgoKYGBge3IgbmVjayBhbm92YTEsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KCiMgbmVjayBBTkNPVkEgMQpuZWNrX2FvdjEgPC0gYW92KG5lY2sgfiBtYWluZ3JvdXAgKiBkaXJlY3Rpb24sIGRhdGEgPSBhb2kzX2RhdGEpCnN1bW1hcnkobmVja19hb3YxKQojIG5lY2tfbHNkMSA8LSBMU0QudGVzdChuZWNrX2FvdjEsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIG5lY2tfbHNkMSRjb21wYXJpc29uCmBgYAoKMi4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgRm9yd2FyZCBvbmx5LgoKYGBge3IgbmVjayBhbm92YTIsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBuZWNrIEFOT1ZBIDIKbmVja19hb3YyIDwtIGFvdihuZWNrIH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKGFvaTNfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCnN1bW1hcnkobmVja19hb3YyKQojIG5lY2tfbHNkMiA8LSBMU0QudGVzdChuZWNrX2FvdjIsICJtYWluZ3JvdXAiLCBncm91cCA9IEZBTFNFKQojIG5lY2tfbHNkMiRjb21wYXJpc29uCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIG5lY2sgYW5vdmEzLCBlY2hvPUZBTFNFLCByZXN1bHRzID0gJ21hcmt1cCd9CiMgbmVjayBBTk9WQSAzCm5lY2tfYW92MyA8LSBhb3YobmVjayB+IG1haW5ncm91cCwgZGF0YSA9IGZpbHRlcihhb2kzX2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSkKc3VtbWFyeShuZWNrX2FvdjMpCiMgbmVja19sc2QzIDwtIExTRC50ZXN0KG5lY2tfYW92MywgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgbmVja19sc2QzJGNvbXBhcmlzb24KYGBgCgo0LiBBTkNPVkEgd2l0aCBmYWN0b3IgRGlyZWN0aW9uLCBhbmQgY292YXJpYXRlIEFvQVNMIGFuZCBBZ2UuCgpgYGB7ciBuZWNrIGFub3ZhNCwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG5lY2sgQU5PVkEgNApuZWNrX2FvdjQgPC0gYW92KG5lY2sgfiBkaXJlY3Rpb24gKiBhb2FzbCAqIGFnZSwgZGF0YSA9IGFvaTNfZGF0YSkKc3VtbWFyeShuZWNrX2FvdjQpCmBgYAoKNS4gUmVncmVzc2lvbiB3aXRoIHZhcmlhYmxlcyBBZ2UgYW5kIEFvQVNMLCBmb3IgRm9yd2FyZCBvbmx5CgpgYGB7ciBuZWNrIGFub3ZhNSwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIG5lY2sgQU5PVkEgNQpuZWNrX2FvdjUgPC0gbG0obmVjayB+IGFvYXNsICogYWdlLCBkYXRhID0gZmlsdGVyKGFvaTNfZGF0YSwgZGlyZWN0aW9uID09ICJmb3J3YXJkIikpCnN1bW1hcnkobmVja19hb3Y1KQpgYGAKCjYuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIFJldmVyc2Ugb25seQoKYGBge3IgbmVjayBhbm92YTYsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBuZWNrIEFOT1ZBIDYKbmVja19hb3Y2IDwtIGxtKG5lY2sgfiBhb2FzbCAqIGFnZSwgZGF0YSA9IGZpbHRlcihhb2kzX2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSkKc3VtbWFyeShuZWNrX2FvdjYpCmBgYAoKIyMgRmFjZUNoZXN0CgpXZSBvcmlnaW5hbGx5IGRlZmluZWQgRmFjZUNoZXN0IHN1Y2ggdGhhdAoKMS4gRmFjZSA9IGV5ZXMgKyBtb3V0aCArIGNoaW4KMS4gQ2hlc3QgPSB1cHBlcmNoZXN0ICsgbWlkY2hlc3QgKyBsb3dlcmNoZXN0CgpCVVQuIENoaW4gaXMgYWN0dWFsbHkgbmVjay4gSXQncyBub3QgZXZlbiBwYXJ0IG9mIHRoZSBmYWNlIGlmIHlvdSB0aGluayBhYm91dCBpdC4gU28gSSdtIHJlZGVmaW5pbmcgRmFjZUNoZXN0IGFzOgoKMS4gRmFjZSA9IGZvcmVoZWFkICsgZXllcyArIG1vdXRoCjEuIENoZXN0ID0gbmVjayArIHVwcGVyY2hlc3QgKyBtaWRjaGVzdCArIGxvd2VyY2hlc3QKClNvIGxldCdzIGRvIHRoaXMuIFRoZW4gc2VlIHdoYXQncyBoYXBwZW5pbmcgYWNyb3NzIGdyb3VwcyBmb3IgRmFjZUNoZXN0LgoKYGBge3IgY2FsY3VsYXRlIGZhY2VjaGVzdCwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIENhbGN1bGF0ZSBmYWNlLCBjaGVzdCwgYW5kIGZhY2VjaGVzdCAtIGFuZCBtb3V0aGV5ZSB0b28KZnVsbGRhdGEgPC0gZnVsbGRhdGEgJT4lCiAgcm93d2lzZSgpICU+JQogIG11dGF0ZShmYWNlID0gc3VtKGZvcmVoZWFkLCBleWVzLCBtb3V0aCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgY2hlc3QgPSBzdW0obmVjaywgdXBwZXJjaGVzdCwgbWlkY2hlc3QsIGxvd2VyY2hlc3QsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIGZhY2VjaGVzdCA9IChmYWNlIC0gY2hlc3QpLyhmYWNlICsgY2hlc3QpLAogICAgICAgICBtb3V0aGV5ZSA9IChtb3V0aCAtIGV5ZXMpLyhtb3V0aCArIGV5ZXMpKQoKIyBmdWxsZGF0YSAlPiUgCiMgICBnYXRoZXIobWV0cmljLCB2YWx1ZSwgYyhmYWNlY2hlc3Rfb2xkLCBmYWNlY2hlc3QpKSAlPiUKIyAgIGdncGxvdChhZXMoeCA9IG1haW5ncm91cCwgeSA9IHZhbHVlLCBmaWxsID0gZGlyZWN0aW9uKSkgKyBnZW9tX2JveHBsb3QoKSArIGZhY2V0X3dyYXAoIm1ldHJpYyIpCmBgYAoKQ29vbC4gTmV4dCB3ZSdsbCBkbyBlcnJvciBiYXIgY2hhcnRzIHVzaW5nIHRoZSBuZXcgRmFjZUNoZXN0IGFjcm9zcyBncm91cHMuIAoKYGBge3IgZmFjZWNoZXN0IGJhcnMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmZhY2VjaGVzdF9pbmZvIDwtIGZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBkaXJlY3Rpb24sIHBhcnRpY2lwYW50KSAlPiUKICBzdW1tYXJpc2UoZmFjZWNoZXN0ID0gbWVhbihmYWNlY2hlc3QsIG5hLnJtID0gVFJVRSkpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oZmFjZWNoZXN0KSwKICAgICAgICAgICAgc2QgPSBzZChmYWNlY2hlc3QpLAogICAgICAgICAgICBuID0gbigpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQobikpCgpnZ3Bsb3QoZmFjZWNoZXN0X2luZm8sIGFlcyh4ID0gbWFpbmdyb3VwLCB5ID0gbWVhbiwgZmlsbCA9IGRpcmVjdGlvbiwgY29sb3IgPSBkaXJlY3Rpb24pKSArCiAgZ2VvbV9wb2ludChzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjUpLCBzaXplID0gMikgKyAKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbi1zZSwgeW1heCA9IG1lYW4rc2UpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuNSksIHdpZHRoID0gMC4zLCBzaXplID0gMSkgKwogIGxhYnModGl0bGUgPSAiRmFjZUNoZXN0IFJhdGlvIiwgc3VidGl0bGUgPSAiRXJyb3IgYmFycyByZXByZXNlbnQgU0UiLCB4ID0gIiIsIHkgPSAiZmFjZWNoZXN0IHJhdGlvIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0xLDEpKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRvdHRlZCIpCmBgYAoKTm93IGxldCdzIGRvIHRoZSBBTk9WQXMuIEFsc28gc2tpcHBpbmcgTFNEcyBoZXJlLiAKCjEuIEFOT1ZBIHdpdGggZmFjdG9ycyBNYWluR3JvdXAgJiBEaXJlY3Rpb24uCgpgYGB7ciBmYWNlY2hlc3QgYW5vdmEgMSwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnLCBtZXNzYWdlPUZBTFNFfQojIENyZWF0ZSB0aGUgcGFydGljaXBhbnQtbGV2ZWwgZGIgKGxldCdzIGFsc28gcG9wIG1vdXRoZXllIGluIHRoaXMgdG9vKQpmY19kYXRhIDwtIGZ1bGxkYXRhICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgc2VsZWN0KGlkLCBtYWluZ3JvdXAsIGhlYXJpbmcsIGFvYXNsLCBhZ2UsIGRpcmVjdGlvbiwgZmFjZWNoZXN0LCBtb3V0aGV5ZSkgJT4lCiAgZ3JvdXBfYnkoaWQsIGRpcmVjdGlvbikgJT4lCiAgbXV0YXRlKGZhY2VjaGVzdCA9IG1lYW4oZmFjZWNoZXN0LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICBtb3V0aGV5ZSA9IG1lYW4obW91dGhleWUsIG5hLnJtID0gVFJVRSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBkaXN0aW5jdCgpCgojIGZhY2VjaGVzdCBBTkNPVkEgMQpmYWNlY2hlc3RfYW92MSA8LSBhb3YoZmFjZWNoZXN0IH4gbWFpbmdyb3VwICogZGlyZWN0aW9uLCBkYXRhID0gZmNfZGF0YSkKc3VtbWFyeShmYWNlY2hlc3RfYW92MSkKIyBmYWNlY2hlc3RfbHNkMSA8LSBMU0QudGVzdChmYWNlY2hlc3RfYW92MSwgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgZmFjZWNoZXN0X2xzZDEkY29tcGFyaXNvbgpgYGAKCjIuIEFOT1ZBIHdpdGggZmFjdG9yIE1haW5Hcm91cCwgZm9yIEZvcndhcmQgb25seS4KCmBgYHtyIGZhY2VjaGVzdCBhbm92YTIsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBmYWNlY2hlc3QgQU5PVkEgMgpmYWNlY2hlc3RfYW92MiA8LSBhb3YoZmFjZWNoZXN0IH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKGZjX2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQpzdW1tYXJ5KGZhY2VjaGVzdF9hb3YyKQojIGZhY2VjaGVzdF9sc2QyIDwtIExTRC50ZXN0KGZhY2VjaGVzdF9hb3YyLCAibWFpbmdyb3VwIiwgZ3JvdXAgPSBGQUxTRSkKIyBmYWNlY2hlc3RfbHNkMiRjb21wYXJpc29uCmBgYAoKMy4gQU5PVkEgd2l0aCBmYWN0b3IgTWFpbkdyb3VwLCBmb3IgUmV2ZXJzZSBvbmx5LiAKCmBgYHtyIGZhY2VjaGVzdCBhbm92YTMsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBmYWNlY2hlc3QgQU5PVkEgMwpmYWNlY2hlc3RfYW92MyA8LSBhb3YoZmFjZWNoZXN0IH4gbWFpbmdyb3VwLCBkYXRhID0gZmlsdGVyKGZjX2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSkKc3VtbWFyeShmYWNlY2hlc3RfYW92MykKIyBmYWNlY2hlc3RfbHNkMyA8LSBMU0QudGVzdChmYWNlY2hlc3RfYW92MywgIm1haW5ncm91cCIsIGdyb3VwID0gRkFMU0UpCiMgZmFjZWNoZXN0X2xzZDMkY29tcGFyaXNvbgpgYGAKCjQuIEFOQ09WQSB3aXRoIGZhY3RvciBEaXJlY3Rpb24sIGFuZCBjb3ZhcmlhdGUgQW9BU0wgYW5kIEFnZS4KCmBgYHtyIGZhY2VjaGVzdCBhbm92YTQsIGVjaG89RkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30KIyBmYWNlY2hlc3QgQU5PVkEgNApmYWNlY2hlc3RfYW92NCA8LSBhb3YoZmFjZWNoZXN0IH4gZGlyZWN0aW9uICogYW9hc2wgKiBhZ2UsIGRhdGEgPSBmY19kYXRhKQpzdW1tYXJ5KGZhY2VjaGVzdF9hb3Y0KQpgYGAKCjUuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIEZvcndhcmQgb25seQoKYGBge3IgZmFjZWNoZXN0IGFub3ZhNSwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIGZhY2VjaGVzdCBBTk9WQSA1CmZhY2VjaGVzdF9hb3Y1IDwtIGxtKGZhY2VjaGVzdCB+IGFvYXNsICogYWdlLCBkYXRhID0gZmlsdGVyKGZjX2RhdGEsIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpKQpzdW1tYXJ5KGZhY2VjaGVzdF9hb3Y1KQpgYGAKCjYuIFJlZ3Jlc3Npb24gd2l0aCB2YXJpYWJsZXMgQWdlIGFuZCBBb0FTTCwgZm9yIFJldmVyc2Ugb25seQoKYGBge3IgZmFjZWNoZXN0IGFub3ZhNiwgZWNobz1GQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQojIGZhY2VjaGVzdCBBTk9WQSA2CmZhY2VjaGVzdF9hb3Y2IDwtIGxtKGZhY2VjaGVzdCB+IGFvYXNsICogYWdlLCBkYXRhID0gZmlsdGVyKGZjX2RhdGEsIGRpcmVjdGlvbiA9PSAicmV2ZXJzZWQiKSkKc3VtbWFyeShmYWNlY2hlc3RfYW92NikKYGBgCgojIEV5ZSBHYXplICYgUGVyZm9ybWFuY2UgQ29ycmVsYXRpb25zCgpOZXh0IHdlJ3JlIGdvaW5nIHRvIGNvcnJlbGF0ZSBvdXIgZXllIGdhemUgbWV0cmljcyAoRXllLCBNb3V0aCwgTmVjaywgYW5kIEZhY2VDaGVzdCkgd2l0aCBsZXhpY2FsIHJlY2FsbCBhbmQgZ2lzdC4gT2theSEgQnV0IHJlbWVtYmVyIHdlIGhhdmUgYSBzbGlnaHRseSBzbWFsbGVyIGRhdGFzZXQgaGVyZSBiZWNhdXNlIHdlJ3ZlIGV4Y2x1ZGVkIHNvbWUgcGFydGljaXBhbnRzIGZvciBoYXZpbmcgYmFkIGV5ZSBkYXRhIChidXQgdGhleSBoYWQgdmFsaWQgYmVoYXZpb3JhbCBkYXRhIHNvIHdlIGtlcHQgdGhlbSBpbiB0aGUgQW9BLVBlcmZvcm1hbmNlIGNvcnJlbGF0aW9ucyBhYm92ZSkuIAoKKipXZSBhbHNvIHJlbW92ZWQgZ2lzdF9mb3J3YXJkIGNvbHVtbi4qKgoKYGBge3IgcmVwYWNrYWdlIGRhdGEgZm9yIGNvcnJlbGF0aW9ucyBhZ2Fpbn0KZXllcGVyZiA8LSBmdWxsZGF0YSAlPiUKICBmaWx0ZXIoZXllX2V4Y2x1ZGUgPT0gRkFMU0UpICU+JQogIHNlbGVjdChwYXJ0aWNpcGFudCwgbWFpbmdyb3VwLCBoZWFyaW5nLCBkaXJlY3Rpb24sIGFjYywgZ2lzdCwgZXllcywgbW91dGgsIG5lY2ssIGZhY2VjaGVzdCkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBwYXJ0aWNpcGFudCwgZGlyZWN0aW9uKSAlPiUKICBtdXRhdGUoZ2lzdCA9IG1lYW4oZ2lzdCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgbGV4ID0gbWVhbihhY2MsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIGV5ZXMgPSBtZWFuKGV5ZXMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIG1vdXRoID0gbWVhbihtb3V0aCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgbmVjayA9IG1lYW4obmVjaywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgZmFjZWNoZXN0ID0gbWVhbihmYWNlY2hlc3QsIG5hLnJtID0gVFJVRSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBzZWxlY3QobWFpbmdyb3VwLCBwYXJ0aWNpcGFudCwgaGVhcmluZywgZGlyZWN0aW9uLCBnaXN0LCBsZXgsIGV5ZXMsIG1vdXRoLCBuZWNrLCBmYWNlY2hlc3QpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgZ2F0aGVyKG1ldHJpYywgdmFsdWUsIGdpc3Q6ZmFjZWNoZXN0KSAlPiUKICB1bml0ZShtZXRyaWN2YWx1ZSwgYyhtZXRyaWMsIGRpcmVjdGlvbiksIHNlcCA9ICJfIikgJT4lCiAgc3ByZWFkKG1ldHJpY3ZhbHVlLCB2YWx1ZSkgJT4lCiAgc2VsZWN0KC1wYXJ0aWNpcGFudCwgLW1haW5ncm91cCkgJT4lCiAgc2VsZWN0KGhlYXJpbmcsIGdpc3RfcmV2ZXJzZWQsIGxleF9mb3J3YXJkLCBsZXhfcmV2ZXJzZWQsIGV5ZXNfZm9yd2FyZCwgZXllc19yZXZlcnNlZCwKICAgICAgICAgbW91dGhfZm9yd2FyZCwgbW91dGhfcmV2ZXJzZWQsIG5lY2tfZm9yd2FyZCwgbmVja19yZXZlcnNlZCwgZmFjZWNoZXN0X2ZvcndhcmQsIGZhY2VjaGVzdF9yZXZlcnNlZCkKCmV5ZXBlcmZfZGVhZiA8LSBleWVwZXJmICU+JSBmaWx0ZXIoaGVhcmluZyA9PSAiRGVhZiIpICU+JSBzZWxlY3QoLWhlYXJpbmcpCmV5ZXBlcmZfaGVhcmluZyA8LSBleWVwZXJmICU+JSBmaWx0ZXIoaGVhcmluZyA9PSAiSGVhcmluZyIpICU+JSBzZWxlY3QoLWhlYXJpbmcpCmV5ZXBlcmZfYWxsIDwtIGV5ZXBlcmYgJT4lIHNlbGVjdCgtaGVhcmluZykKCgojIENvcnJlbGF0aW9ucyBmb3IgRGVhZgpwcmludCgiREVBRiBDb3JyZWxhdGlvbnMgLSBQZWFyc29uJ3MgciIpCiNjb3JzdGFyc2wobGV4Z2lzdF9kZWFmKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGV5ZXBlcmZfZGVhZikpJHIKcHJpbnQoIkRFQUYgQ29ycmVsYXRpb25zIC0gUC12YWx1ZXMiKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGV5ZXBlcmZfZGVhZikpJFAKY2F0KHBhc3RlKCIiLCJcbiIsIiIpKQoKIyBDb3JyZWxhdGlvbnMgZm9yIEhlYXJpbmcKcHJpbnQoIkhFQVJJTkcgQ29ycmVsYXRpb25zIC0gUGVhcnNvbidzIHIiKQojY29yc3RhcnNsKGxleGdpc3RfaGVhcmluZykKSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChleWVwZXJmX2hlYXJpbmcpKSRyCnByaW50KCJIRUFSSU5HIENvcnJlbGF0aW9ucyAtIFAtdmFsdWVzIikKSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChleWVwZXJmX2hlYXJpbmcpKSRQCmNhdChwYXN0ZSgiIiwiXG4iLCIiKSkKCiMgQ29ycmVsYXRpb25zIGZvciBBbGwKcHJpbnQoIkFMTCBDb3JyZWxhdGlvbnMgLSBQZWFyc29uJ3MgciIpCiNjb3JzdGFyc2wobGV4Z2lzdF9hbGwpCkhtaXNjOjpyY29ycihhcy5tYXRyaXgoZXllcGVyZl9hbGwpKSRyCnByaW50KCJBTEwgQ29ycmVsYXRpb25zIC0gUC12YWx1ZXMiKQpIbWlzYzo6cmNvcnIoYXMubWF0cml4KGV5ZXBlcmZfYWxsKSkkUAoKYGBgCgpJJ20gYWxzbyBpbmNsdWRpbmcgbmljZWx5IGZvcm1hdHRlZCB0YWJsZXMgd2l0aCAqKiogaW5kaWNhdG9ycyBvZiBzaWduaWZpY2FuY2UgZm9yIHF1aWNrIHJlZmVyZW5jaW5nLiBPcmRlcjogRGVhZiwgSGVhcmluZywgQWxsLiAKCmBgYHtyIHByZXR0eSBjb3JyZWxhdGlvbnMgZm9yIGV5ZXBlcmZ9CmNvcnN0YXJzbChleWVwZXJmX2RlYWYpCmNvcnN0YXJzbChleWVwZXJmX2hlYXJpbmcpCmNvcnN0YXJzbChleWVwZXJmX2FsbCkKYGBgCgpBbmQgdGhlIGNvcnJlbGF0aW9uIHRhYmxlLgoKYGBge3IgZXllcGVyZiBjb3JyZWxhdGlvbiBjaGFydHMsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KZ2dwYWlycyhleWVwZXJmLCBjb2x1bW5zID0gYygyOjExKSwgYWVzKGNvbG9yID0gaGVhcmluZykpCmBgYAoKIyBIZWF0IE1hcHMKQW5kIGZpbmFsbHksIHdlJ3JlIGdvaW5nIHRvIGRvIGhlYXQgbWFwcy4gCmBgYHtyIGhlYXQgbWFwfQpleWVnYXplX2hlYXQgPC0gZnVsbGRhdGEgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcihleWVfZXhjbHVkZSA9PSBGQUxTRSkgJT4lCiAgc2VsZWN0KGlkOmRpcmVjdGlvbiwgYmVsbHksIGxvd2VyY2hlc3QsIG1pZGNoZXN0LCB1cHBlcmNoZXN0LCBuZWNrLCBtb3V0aCwgZXllcywgZm9yZWhlYWQpICU+JQogIGdhdGhlcihhb2ksIHBlcmNlbnQsIGJlbGx5OmZvcmVoZWFkKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsIHBhcnRpY2lwYW50LCBkaXJlY3Rpb24sIGFvaSkgJT4lCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtPVRSVUUpKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsZGlyZWN0aW9uLGFvaSkgJT4lCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtPVRSVUUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZmlsdGVyKCFpcy5uYShhb2kpKSAlPiUKICBtdXRhdGUoYW9pID0gZmFjdG9yKGFvaSxsZXZlbHM9YygiYmVsbHkiLCJsb3dlcmNoZXN0IiwibWlkY2hlc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1cHBlcmNoZXN0IiwibmVjayIsIm1vdXRoIiwiZXllcyIsImZvcmVoZWFkIikpKQoKZXllZ2F6ZV9oZWF0X2FsbCA8LSBmdWxsZGF0YSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZmlsdGVyKGV5ZV9leGNsdWRlID09IEZBTFNFKSAlPiUKICBzZWxlY3QoaWQ6ZGlyZWN0aW9uLCBiZWxseSwgbG93ZXJjaGVzdCwgbWlkY2hlc3QsIHVwcGVyY2hlc3QsIG5lY2ssIG1vdXRoLCBleWVzLCBmb3JlaGVhZCkgJT4lCiAgZ2F0aGVyKGFvaSwgcGVyY2VudCwgYmVsbHk6Zm9yZWhlYWQpICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCxwYXJ0aWNpcGFudCxkaXJlY3Rpb24sYW9pKSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQsIG5hLnJtPVRSVUUpKSAlPiUKICBncm91cF9ieShtYWluZ3JvdXAsZGlyZWN0aW9uLGFvaSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShwZXJjZW50ID0gbWVhbihwZXJjZW50LCBuYS5ybT1UUlVFKSkgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLGFvaSkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShwZXJjZW50ID0gbWVhbihwZXJjZW50LCBuYS5ybT1UUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcighaXMubmEoYW9pKSkgJT4lCiAgbXV0YXRlKGFvaSA9IGZhY3Rvcihhb2ksbGV2ZWxzPWMoImJlbGx5IiwibG93ZXJjaGVzdCIsIm1pZGNoZXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidXBwZXJjaGVzdCIsIm5lY2siLCJtb3V0aCIsImV5ZXMiLCJmb3JlaGVhZCIpKSkKCmdncGxvdChleWVnYXplX2hlYXQsIGFlcyh4ID0gbWFpbmdyb3VwLCB5ID0gYW9pKSkgKwogIGdlb21fdGlsZShhZXMoZmlsbD1wZXJjZW50KSxjb2xvcj0ibGlnaHRncmF5IixuYS5ybT1UUlVFKSArIAojICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJsaWdodGJsdWUiLGhpZ2ggPSAic3RlZWxibHVlIikgKwojICBzY2FsZV9maWxsX2Rpc3RpbGxlcih0eXBlPSJkaXYiLCBwYWxldHRlID0gIlJkWWxCdSIpICsKICBzY2FsZV9maWxsX3ZpcmlkaXMob3B0aW9uID0gInZpcmlkaXMiLCBkaXJlY3Rpb249LTEsIGxpbWl0cyA9IGMoMCwuNzUpKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LGhqdXN0PTEpKSArIGZhY2V0X2dyaWQoLiB+IGRpcmVjdGlvbikgKwogIHlsYWIoIiIpICsgeGxhYigiIikgKyBnZ3RpdGxlKCJFeWUgR2F6ZSBIZWF0IE1hcCwgYnkgRGlyZWN0aW9uIikKCmdncGxvdChleWVnYXplX2hlYXRfYWxsLCBhZXMoeCA9IG1haW5ncm91cCwgeSA9IGFvaSkpICsKICBnZW9tX3RpbGUoYWVzKGZpbGw9cGVyY2VudCksY29sb3I9ImxpZ2h0Z3JheSIsbmEucm09VFJVRSkgKyAKIyAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAibGlnaHRibHVlIixoaWdoID0gInN0ZWVsYmx1ZSIpICsKIyAgc2NhbGVfZmlsbF9kaXN0aWxsZXIodHlwZT0iZGl2IiwgcGFsZXR0ZSA9ICJSZFlsQnUiKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzKG9wdGlvbiA9ICJ2aXJpZGlzIiwgZGlyZWN0aW9uPS0xLCBsaW1pdHMgPSBjKDAsLjc1KSkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT00NSxoanVzdD0xKSkgKwogIHlsYWIoIiIpICsgeGxhYigiIikgKyBnZ3RpdGxlKCJFeWUgR2F6ZSBIZWF0IE1hcCAoRGlyZWN0aW9uIENvbGxhcHNlZCkiKQpgYGAKCiMgU3VtbWFyeQoKQmVsb3cgYXJlIHRoZSBwLXZhbHVlcyBmcm9tIHRoZSBBTk9WQXMgd2l0aCA0IE1haW5Hcm91cHMuIEkgbmV2ZXIgaW5jbHVkZWQgQWdlIGFzIGEgY292YXJpYXRlIGJlY2F1c2UgaXQgbmV2ZXIgaW1wcm92ZWQgdGhlIG1vZGVsLiBJIGluY2x1ZGVkIGFsbCBBTk9WQXMgZm9yIEdpc3QgYW5kIExleCBSZWNhbGwsIGFuZCBBTk9WQXMgZm9yIGFueSBleWUgQU9JIG9yIHJhdGlvIHdhcyBpbmNsdWRlZCBvbmx5IGlmIGVpdGhlciBtYWluZ3JvdXAgb3IgZGlyZWN0aW9uIHdhcyBzaWduaWZpY2FudC4gRGVhZmVhcmx5LURlYWZsYXRlIHNob3dzIHRoZSBMU0QgcC12YWx1ZSBmb3IgdGhhdCBjb21wYXJpc29uLgpgYGB7ciByZXN1bHRzMSwgcm93cy5wcmludCA9IDIwfQpyZXN1bHRzMSA8LSBzdHJ1Y3R1cmUobGlzdChtb2RlbCA9IGMoImdpc3QtbWFpbmdyb3VwLWJvdGgiLCAiZ2lzdC1tYWluZ3JvdXAtZnciLCAKImdpc3QtbWFpbmdyb3VwLXJ2IiwgImxleHJlY2FsbC1tYWluZ3JvdXAtYm90aCIsICJsZXhyZWNhbGwtbWFpbmdyb3VwLWZ3IiwgCiJsZXhyZWNhbGwtbWFpbmdyb3VwLXJ2IiwgIm1vdXRoLW1haW5ncm91cC1ib3RoIiwgInVwcGVyY2hlc3QtbWFpbmdyb3VwLWJvdGgiLCAKInVwcGVyY2hlc3QtbWFpbmdyb3VwLXJ2IiwgImZhY2VjaGVzdC1tYWluZ3JvdXAtYm90aCIsICJtb3V0aGV5ZS1tYWluZ3JvdXAtYm90aCIKKSwgbWFpbmdyb3VwID0gYygwLCAwLCAwLjAxLCAwLCAwLjA0LCAwLjAyLCAwLjA2LCAwLCAwLjAxLCAwLjEsIAowLjA1KSwgZGlyZWN0aW9uID0gYygwLCBOQSwgTkEsIDAsIE5BLCBOQSwgMC4wNiwgMC4xNiwgTkEsIDAuMDcsIAowLjQ4KSwgYGRlYWZlYXJseS1kZWFmbGF0ZWAgPSBjKDAuMSwgMC42OSwgMC4wMiwgMC4xMSwgMC45NSwgCjAuMDYsIDAuMzgsIDAuOTQsIDAuNTIsIDAuMDgsIDAuNjgpKSwgLk5hbWVzID0gYygibW9kZWwiLCAibWFpbmdyb3VwIiwgCiJkaXJlY3Rpb24iLCAiZGVhZmVhcmx5LWRlYWZsYXRlIiksIGNsYXNzID0gYygidGJsX2RmIiwgInRibCIsIAoiZGF0YS5mcmFtZSIpLCByb3cubmFtZXMgPSBjKE5BLCAtMTFMKSkKCnJlc3VsdHMxCmBgYAoKQW5kIGJlbG93IGFyZSB0aGUgcC12YWx1ZXMgZnJvbSB0aGUgQU5DT1ZBcyB3aXRoIEhlYXJpbmcgJiBBb0FTTC4gSSBpbmNsdWRlZCBhbGwgQU5DT1ZBcyBmb3IgR2lzdCBhbmQgTGV4IFJlY2FsbCwgYW5kIEFOQ09WQXMgZm9yIGFueSBleWUgQU9JIG9yIHJhdGlvIHdhcyBpbmNsdWRlZCBvbmx5IGlmIGFueSBtYWluIGZhY3RvciB3YXMgc2lnbmlmaWNhbnQuIExTRCBjb21wYXJpc29ucyBhcmUgbm90IG5lZWRlZCBiZWNhdXNlIHRoZXJlJ3Mgb25seSAyIGxldmVscyBpbiBlYWNoIGdyb3VwIQoKYGBge3IgcmVzdWx0czIsIHJvd3MucHJpbnQgPSAyNX0KcmVzdWx0czIgPC0gc3RydWN0dXJlKGxpc3QobW9kZWwgPSBjKCJnaXN0LWJvdGgiLCAiZ2lzdC1mdyIsICJnaXN0LXJ2IiwgImxleC1ib3RoIiwgCiJsZXgtZnciLCAibGV4LXJ2IiwgImZvcmVoZWFkLWZ3IiwgIm1vdXRoLWJvdGgiLCAibW91dGgtcnYiLCAKInVwcGVyY2hlc3QtYm90aCIsICJ1cHBlcmNoZXN0LXJ2IiwgImZhY2VjaGVzdC1ib3RoIiwgIm1vdXRoZXllLWJvdGgiCiksIGhlYXJpbmcgPSBjKDAsIDAuMDAsIDAuMDEsIDAuMDEsIDAuMjIsIDAuMDMsIDAuMDYsIDAuMDEsIAowLjA0LCAwLjAxLCAwLjAxLCAwLjM1LCAwLjA3KSwgZGlyZWN0aW9uID0gYygwLCBOQSwgTkEsIDAsIE5BLCAKTkEsIE5BLCAwLjA1LCBOQSwgMC4yMSwgTkEsIDAuMDUsIDAuNTIpLCBhb2FzbCA9IGMoMC4yMiwgMC43NywgCjAuMTksIDAuNTYsIDAuNTgsIDAuMjUsIDAuMDgsIDAuMDYsIDAuMTIsIDAuNjgsIDAuOTUsIDAuMTIsIDAuNDQKKSwgYWdlID0gYygwLjA4LCAwLjAxLCAwLjg2LCAwLjA5LCAwLjAyLCAwLjcsIDAuNjgsIDAuMjgsIDAuNSwgCjAuMDIsIDAuMDgsIDAuMDAsIDAuMjEpKSwgLk5hbWVzID0gYygibW9kZWwiLCAiaGVhcmluZyIsICJkaXJlY3Rpb24iLCAKImFvYXNsIiwgImFnZSIpLCBjbGFzcyA9IGMoInRibF9kZiIsICJ0YmwiLCAiZGF0YS5mcmFtZSIpLCByb3cubmFtZXMgPSBjKE5BLCAKLTEzTCkpCnJlc3VsdHMyCmBgYAoKRmluYWxseSwgdGhlIGNvcnJlbGF0aW9ucyBmb3IgRGVhZiBhbmQgSGVhcmluZyBzZXBhcmF0ZWx5IGFyZSBub3Qgc2lnbmlmaWNhbnQuIEJ1dCB0aGVyZSBhcmUgc2lnbmlmaWNhbnQgY29ycmVsYXRpb25zIGFjcm9zcyBhbGwgcGFydGljaXBhbnRzLiBJIHdvcnJ5IGl0IGlzIGNhdXNlZCBieSBIZWFyaW5nTm92aWNlLCB0aG91Z2guLi4KCmBgYHtyIGNvcnJlbGF0aW9uIHRhYmxlfQpyZXN1bHRzMyA8LSB0cmliYmxlKAogIH4gbWV0cmljLCB+IEFvQVNMY29ycmVsYXRpb25SdmFsdWUsIH4gUHZhbHVlLAogICJnaXN0LWZ3IiwgLTAuMzIsIDAuMDE5LAogICJnaXN0LXJ2IiwgLTAuMzksIDAuMDA0LAogICJsZXgtZnciLCAtMC4wOCwgMC41NjcsCiAgImxleC1ydiIsIC0wLjM0LCAwLjAxNAopCnJlc3VsdHMzCmBgYAoKIyBUZXJuYXJ5IFBsb3RzCgpMZXQncyBtYWtlIHRyaWFuZ2xlIHBsb3RzLiAiV2hhdD8iIHlvdSBzYXkuIFJlYWQgb24uIAoKYGBge3IgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGdndGVybikKZnVsbGRhdGEgJT4lIAogIGdndGVybihhZXMoeCA9IGV5ZXMsIHkgPSBtb3V0aCwgeiA9IG5lY2spKSArIGZhY2V0X2dyaWQoZGlyZWN0aW9uIH4gbWFpbmdyb3VwKSArIHN0YXRfZGVuc2l0eV90ZXJuKGdlb209J3BvbHlnb24nLCBhZXMoZmlsbD0uLmxldmVsLi4pLCBiaW5zPTQpICsgZ2VvbV9wb2ludChjb2xvciA9ICJ3aGl0ZSIsIGFscGhhID0gMC41KSArIHRoZW1lX2J3KCkKCmZ1bGxkYXRhICU+JSAKICBnZ3Rlcm4oYWVzKHggPSBleWVzLCB5ID0gbW91dGgsIHogPSBuZWNrKSkgKyBmYWNldF9ncmlkKGRpcmVjdGlvbiB+IG1haW5ncm91cCkgKyBnZW9tX2NvbmZpZGVuY2VfdGVybihicmVha3MgPSBjKC41KSwgY29sb3IgPSAicmVkIikgKyBnZW9tX3BvaW50KCkgKyB0aGVtZV9idygpCmBgYAoKIyBSYWluJ3MgTm90ZXMKQWJvdXQgQWR1bHRzOgoKLUkgdGhpbmsgSSB3YW50IHRvIHdyaXRlIGl0IHVwIGFzIGFuIEFOQ09WQSwgd2l0aCBkaXJlY3Rpb24gaW5jbHVkZWQuICBBbmQgTFNEIGNvbXBhcmlzb25zIGluc3RlYWQgb2YgVHVrZXkuICAoSSB3aWxsIGRvIG15IG93biBjb3JyZWN0aW9ucykKLVlvdSBvZnRlbiBoYXZlIG9uZSBsaW5lcnMgc3VtbWFyaXppbmcgcmVzdWx0cywgaW4gYWxsIHRhYnMsIHRob3NlIGFyZSBuaWNlLCBrZWVwIHRoZW0gY29taW5nLgotKElmIHlvdSBoYXZlIHJlYXNvbnMgdG8gcHJlc2VudCBhbnl0aGluZyBvdGhlciB0aGFuIHRoZSBBTkNPVkEsIHB1dCB0aGF0IGluIHlvdXIgcmVzdWx0cyB0YWIpCiAKSSB0aGluayBpZiB3ZSBkbyBpdCB0aGlzIHdheSB0aGVuIHdlIGdldCBhIHJlYWxseSBpbXBvcnRhbnQgc3RvcnkgdG8gdGVsbDogIFRoYXQgdGhlICpjcml0aWNhbCogQW9BIGN1dG9mZiBpcyBiZWxvdyA0IHZzIGFib3ZlIDQgeWVhcnMgb2YgYWdlICh0d28gZ3JvdXBzIDAtNCB2cyA0LTEzKS4gIFRoaXMgc3VnZ2VzdCBlYXJseSBBU0wgaXMgaW1wb3J0YW50LiAgCgpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojIEdpc3QgYXMgYmlub21pYWwgbG9naXQtbGluayBmdW5jdGlvbiBtb2RlbApnaXN0X2dsbW0gPC0gZ2xtZXIoZ2lzdCB+IGRpcmVjdGlvbiAqIG1haW5ncm91cCArICgxfGlkKSArICgxfHN0b3J5KSwgZGF0YSA9IGZ1bGxkYXRhLCBmYW1pbHk9Ymlub21pYWwgKGxpbms9ImxvZ2l0IikpCnN1bW1hcnkoZ2lzdF9nbG1tKQpgYGAK